信号灯文件锁linux线程,linux——线程同步(互斥量、条件变量、信号灯、文件锁)...
一、說明
linux的線程同步涉及:
1、互斥量
2、條件變量
3、信號燈
4、文件讀寫鎖
信號燈很多時候被稱為信號量,但個人仍覺得叫做信號燈比較好,因為可以與“SYSTEM V IPC的信號量”相區(qū)分(如有不同意見,歡迎探討)。
二、互斥量
1、定義
互斥鎖允許我們鎖住某個對象(某個變量、某段代碼等),使得每次只能有一個線程訪問他。我們在對需要保護的對象進行操作前,先把互斥鎖上鎖,如果上鎖成功,就不會有別的線程再來操作被保護的對象。如果上鎖不成功,線程就會阻塞(可能是有別的線程已經(jīng)把互斥鎖鎖住了),直到互斥鎖被打開。從而保護了要保護的對象。
2、相關(guān)函數(shù)
a.pthread_mutex_init
函數(shù)原型:
#include
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t?*mutexattr);
功能:初始化互斥鎖
參數(shù):mutex為pthread_mutex_t類型的變量的地址,也就是互斥鎖的名字;
mutexattr為pthread_mutexattr_t類型的變量地址,用于設(shè)置鎖的屬性,默認可以設(shè)為NULL;
返回:成功0,錯誤返回錯誤代碼。
備注:初始化互斥鎖還有個簡便的方法,比如對 pthread_mutex_t a; 進行初始化,則直接寫成:pthread_mutex_t a = PTHREAD_MUTEX_INITIALIZER; 即可。
b.pthread_mutex_destroy
函數(shù)原型:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:銷毀互斥鎖
參數(shù):mutex為要銷毀的互斥鎖的地址
返回:成功0,錯誤返回錯誤代碼。
c.pthread_mutex_lock
函數(shù)原型:
int pthread_mutex_lock(pthread_mutex_t *mutex));
功能:上鎖
參數(shù):同上
返回:同上
d.pthread_mutex_unlock
函數(shù)原型:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:解鎖
參數(shù):同上
返回:同上
3、例程
#include
#include
pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
int cnt=0;
void *func1(void *b)
{
int a=2000;
usleep(rand()%2000);
while(a--)
{
printf("11111=%d.\n",a);
printf("\tpthread 1 start to lock.\n");
pthread_mutex_lock (&mylock);
printf("\tpthread 1 locked.\n");
cnt++;
printf("\t++cnt=%d\n",cnt);
printf("\tpthread 1 start to unlock.\n");
pthread_mutex_unlock (&mylock);
printf("\tpthread 1 unlocked.\n");
}
}
void *func2(void *b)
{
int a=2000;
usleep(rand()%2000);
while(a--)
{
printf("22222=%d.\n",a);
printf("\tpthread 2 start to lock.\n");
pthread_mutex_lock (&mylock);
printf("\tpthread 2 locked.\n");
if(cnt>0)
{
cnt--;
printf("\t--cnt=%d\n",cnt);
}
printf("\tpthread 2 start to unlock.\n");
pthread_mutex_unlock (&mylock);
printf("\tpthread 2 unlocked.\n");
if(!cnt)
{
usleep(1);
}
}
}
int main(void)
{
pthread_t a,b;
pthread_create(&a, NULL, func1, (void*)0 );
pthread_create(&b, NULL, func2, (void*)0 );
pthread_join (a, NULL);
pthread_join (b, NULL);
return 0;
}程序中,cnt即為要保護的對象,兩個線程,同一時刻只能有一個線程在訪問這個對象。
三、條件變量
1、定義
條件變量與互斥量一起使用時,允許線程以無競爭的方式等待特定條件的發(fā)生。條件本身受互斥量的保護,線程在改變條件狀態(tài)前,必須先鎖住互斥量,其他線程在獲得互斥量之前不會覺察到這種變化(因為互斥量被正在改變條件的線程鎖著,其他線程沒有獲得互斥量就沒有機會覺察到變化)
2、相關(guān)函數(shù)
a.pthread_cond_init
函數(shù)原型:
int pthread_cond_init (pthread_cond_t * cond,?const pthread_condattr_t *cond_attr);
功能:初始化條件變量
參數(shù):cond條件變量名的地址
cond_attr為條件變量的屬性
返回:成功0,錯誤返回錯誤編號
備注:簡便的初始化方法:pthread_cond_t a = PTHREAD_COND_INITIALIZER;
b.pthread_cond_destroy
函數(shù)原型:
int pthread_cond_destroy (pthread_cond_t *cond);
功能:銷毀條件變量
參數(shù):cond條件變量名的地址
返回:成功0,錯誤返回錯誤代碼
c.pthread_cond_wait
函數(shù)原型:
int pthread_cond_wait (pthread_cond_t *cond,?pthread_mutex_t *mutex);
功能:等待互斥鎖mutex下的條件cond的發(fā)生
參數(shù):cond為要等待的條件變量
mutex為保護條件變量的互斥鎖
返回:成功0,錯誤返回錯誤代碼
d.pthread_cond_signal
函數(shù)原型:
int pthread_cond_signal (pthread_cond_t *cond);
功能:發(fā)送條件變量cond
參數(shù):cond為要發(fā)送的條件變量
返回:成功0,否則返回錯誤編號 備注:
只通知某一個等待該條件的線程
e.pthread_cond_broadcast
功能:發(fā)送條件變量cond
參數(shù):cond為要發(fā)送的條件變量
返回:成功0,否則返回錯誤編號
備注:通知所有等待該條件的線程
3、例程(與某嵌入式面試題類似:三個線程各自打印A、B、C,要求按順序ACBCACBC輸出)
#include
#include
#include
int sequence=1;
int eat = 1;
pthread_mutex_t productor_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t productor_mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t my_cond1 = PTHREAD_COND_INITIALIZER;
void *productor1()
{
int my_sequence = 1;
while(1)
{
pthread_mutex_lock(&productor_mutex);
while(sequence!=my_sequence)
{
pthread_cond_wait (&my_cond, &productor_mutex);
}
pthread_mutex_lock(&productor_mutex1);
while(eat!=1)
{
pthread_cond_wait (&my_cond1, &productor_mutex1);
}
printf("A ");
eat=0;
pthread_cond_broadcast (&my_cond1);
pthread_mutex_unlock (&productor_mutex1);
sequence=2;
pthread_cond_broadcast(&my_cond);
pthread_mutex_unlock (&productor_mutex);
}
return 0;
}
void *productor2()
{
int my_sequence=2;
while(1)
{
pthread_mutex_lock(&productor_mutex);
while(sequence!=my_sequence)
{
pthread_cond_wait (&my_cond, &productor_mutex);
}
pthread_mutex_lock(&productor_mutex1);
while(eat!=1)
{
pthread_cond_wait (&my_cond1, &productor_mutex1);
}
printf("B ");
eat=0;
pthread_cond_broadcast (&my_cond1);
pthread_mutex_unlock (&productor_mutex1);
sequence=1;
pthread_cond_broadcast (&my_cond);
pthread_mutex_unlock (&productor_mutex);
}
return 0;
}
void *consumer()
{
long a=200;
while(a--)
{
pthread_mutex_lock(&productor_mutex1);
while(eat!=0)
{
pthread_cond_wait (&my_cond1, &productor_mutex1);
}
printf("C ");
eat=1;
pthread_cond_broadcast (&my_cond1);
pthread_mutex_unlock (&productor_mutex1);
}
return 0;
}
int main(void)
{
pthread_t pth1=0,pth2=0,pth3=0;
int err=-1;
void *tret=NULL;
err = pthread_create(&pth1,NULL,productor1,NULL);
if(err)
{
printf("creat pthread productor failed!\n");
exit(1);
}
err = pthread_create(&pth2,NULL,productor2,NULL);
if(err)
{
printf("creat pthread productor failed!\n");
exit(1);
}
err = pthread_create(&pth3,NULL,consumer,NULL);
if(err)
{
printf("creat pthread consumer failed!\n");
exit(1);
}
err = pthread_join(pth3,&tret);
if(err)
printf("can't join pthread consumer!\n");
else
printf("pthread consumer exit with %d!\n",(int)tret);
pthread_cancel(pth1);
pthread_cancel(pth2);
exit(0);
}
四、信號燈
1、定義
又叫做計數(shù)信號量,post一次信號量的值+1;wait一次,信號量的值-1,如果信號量的值已經(jīng)為0,則wait將阻塞直至信號量的值>0;
2、相關(guān)函數(shù)
a.sem_init
函數(shù)原型:
#include
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:初始化信號量
參數(shù):sem為要初始化的信號量地址
value為初始化設(shè)置的值
返回:X?
b.sem_destroy
函數(shù)原型:
int sem_destroy(sem_t * sem);
功能:銷毀信號量
參數(shù):sem要銷毀的信號量地址
返回:X?
c.sem_post
函數(shù)原型:
int sem_post(sem_t * sem);
功能:信號量值+1
參數(shù):
返回:
d.sem_wait
函數(shù)原型:
int sem_wait(sem_t * sem);
功能:信號量值-1
參數(shù):sem要銷毀的信號量地址
返回:X?
e.sem_getvalue
函數(shù)原型:
int sem_getvalue(sem_t * sem);
功能:獲取信號量當前值
參數(shù):
返回:X?
3、例程
五、文件讀寫鎖
1、定義
2、相關(guān)函數(shù)
3、例程
總結(jié)
以上是生活随笔為你收集整理的信号灯文件锁linux线程,linux——线程同步(互斥量、条件变量、信号灯、文件锁)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux mkdir绝对路径,linu
- 下一篇: 迪士尼任命耐克执行主席为新任董事长,反对