700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 信号灯文件锁linux线程 linux——线程同步(互斥量 条件变量 信号灯 文件锁)...

信号灯文件锁linux线程 linux——线程同步(互斥量 条件变量 信号灯 文件锁)...

时间:2019-05-17 14:47:52

相关推荐

信号灯文件锁linux线程 linux——线程同步(互斥量 条件变量 信号灯 文件锁)...

一、说明

linux的线程同步涉及:

1、互斥量

2、条件变量

3、信号灯

4、文件读写锁

信号灯很多时候被称为信号量,但个人仍觉得叫做信号灯比较好,因为可以与“SYSTEM V IPC的信号量”相区分(如有不同意见,欢迎探讨)。

二、互斥量

1、定义

互斥锁允许我们锁住某个对象(某个变量、某段代码等),使得每次只能有一个线程访问他。我们在对需要保护的对象进行操作前,先把互斥锁上锁,如果上锁成功,就不会有别的线程再来操作被保护的对象。如果上锁不成功,线程就会阻塞(可能是有别的线程已经把互斥锁锁住了),直到互斥锁被打开。从而保护了要保护的对象。

2、相关函数

a.pthread_mutex_init

函数原型:

#include

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t*mutexattr);

功能:初始化互斥锁

参数:mutex为pthread_mutex_t类型的变量的地址,也就是互斥锁的名字;

mutexattr为pthread_mutexattr_t类型的变量地址,用于设置锁的属性,默认可以设为NULL;

返回:成功0,错误返回错误代码。

备注:初始化互斥锁还有个简便的方法,比如对 pthread_mutex_t a; 进行初始化,则直接写成:pthread_mutex_t a = PTHREAD_MUTEX_INITIALIZER; 即可。

b.pthread_mutex_destroy

函数原型:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

功能:销毁互斥锁

参数:mutex为要销毁的互斥锁的地址

返回:成功0,错误返回错误代码。

c.pthread_mutex_lock

函数原型:

int pthread_mutex_lock(pthread_mutex_t *mutex));

功能:上锁

参数:同上

返回:同上

d.pthread_mutex_unlock

函数原型:

int pthread_mutex_unlock(pthread_mutex_t *mutex);

功能:解锁

参数:同上

返回:同上

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、定义

条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定条件的发生。条件本身受互斥量的保护,线程在改变条件状态前,必须先锁住互斥量,其他线程在获得互斥量之前不会觉察到这种变化(因为互斥量被正在改变条件的线程锁着,其他线程没有获得互斥量就没有机会觉察到变化)

2、相关函数

a.pthread_cond_init

函数原型:

int pthread_cond_init (pthread_cond_t * cond,const pthread_condattr_t *cond_attr);

功能:初始化条件变量

参数:cond条件变量名的地址

cond_attr为条件变量的属性

返回:成功0,错误返回错误编号

备注:简便的初始化方法:pthread_cond_t a = PTHREAD_COND_INITIALIZER;

b.pthread_cond_destroy

函数原型:

int pthread_cond_destroy (pthread_cond_t *cond);

功能:销毁条件变量

参数:cond条件变量名的地址

返回:成功0,错误返回错误代码

c.pthread_cond_wait

函数原型:

int pthread_cond_wait (pthread_cond_t *cond,pthread_mutex_t *mutex);

功能:等待互斥锁mutex下的条件cond的发生

参数:cond为要等待的条件变量

mutex为保护条件变量的互斥锁

返回:成功0,错误返回错误代码

d.pthread_cond_signal

函数原型:

int pthread_cond_signal (pthread_cond_t *cond);

功能:发送条件变量cond

参数:cond为要发送的条件变量

返回:成功0,否则返回错误编号 备注:

只通知某一个等待该条件的线程

e.pthread_cond_broadcast

功能:发送条件变量cond

参数:cond为要发送的条件变量

返回:成功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、定义

又叫做计数信号量,post一次信号量的值+1;wait一次,信号量的值-1,如果信号量的值已经为0,则wait将阻塞直至信号量的值>0;

2、相关函数

a.sem_init

函数原型:

#include

int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:初始化信号量

参数:sem为要初始化的信号量地址

value为初始化设置的值

返回:X?

b.sem_destroy

函数原型:

int sem_destroy(sem_t * sem);

功能:销毁信号量

参数:sem要销毁的信号量地址

返回:X?

c.sem_post

函数原型:

int sem_post(sem_t * sem);

功能:信号量值+1

参数:

返回:

d.sem_wait

函数原型:

int sem_wait(sem_t * sem);

功能:信号量值-1

参数:sem要销毁的信号量地址

返回:X?

e.sem_getvalue

函数原型:

int sem_getvalue(sem_t * sem);

功能:获取信号量当前值

参数:

返回:X?

3、例程

五、文件读写锁

1、定义

2、相关函数

3、例程

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。