一.信号量(semaphore)
mutex变量是非0即1的,可看作一种资源的可用数量,初始化时mutex是1,表示有一个可用资源,加锁时获得该资源,将mutex减到0,表示不再有可用资源,解锁时释放该资源,将mutex重新加到1,表示又有了一个可用资源。
semaphore和mutex类似,表示可用资源的数量,和mutex不同的是这个数量可以大于1。
也就是说,当信号量描述的资源数目是1时,此时的信号量和互斥锁相同。
下面所讲的是POSIX semaphore库函数,这种信号不仅可用于同一进程的线程间同步,也可用于不同进程间的同步。
所用的函数如下:
#include<semaphore.h>
int sem_init(sem_t *sem,int pshared,unsigned int value);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_destroy(sem_t *sem);
semaphore变量的类型是sem_t,sem_init()初始化一个semaphore变量,value参数表示可用资源的数量,pshared参数为0表示信号量用于同一进程的线程同步。
调用sem_wait()可以获得资源(P操作),使semaphore的值减1,如果调用sem_wait()时semaphore的值已经是0,则挂起等待;如果不希望挂起等待,可以调用sem_try_wait();调用sem_post()可以释放资源(V操作),使semaphore得值加1,同时唤醒挂起等待的线程。
二.基于固定大小的环形队列来实现生产者消费者模型
1 #include<stdio.h>
2 #include<semaphore.h>
3 #include<pthread.h>
4 #define _SIZE_ 20
5 sem_t blank;
6 sem_t data;
7 pthread_mutex_t lock1;
8 pthread_mutex_t lock2;
9 int buf[_SIZE_];
10 void *product(void *arg)
11 {
12 int i=0;
13 int count=0;
14 while(1)
15 {
16 //pthread_mutex_lock(&lock1); //把生产者之间的锁加在信号量外面(不可取)
17 sem_wait(&blank);
18 pthread_mutex_lock(&lock1); //把生产者之间的锁加在信号量的里面(可取)
19 buf[i]=count++;
20 sleep(rand()%3);
21 pthread_mutex_unlock(&lock1);
22 sem_post(&data);
23 i++;
24 i%=_SIZE_;
25 //pthread_mutex_unlock(&lock1);
26 }
27 }
28 void *consumer(void *arg)
29 {
30 int i=0;
31 int count=0;
32 while(1)
33 {
34 //pthread_mutex_lock(&lock2); //把消费者之间的锁加在信号量的外面(不可取)
35 sem_wait(&data);
36 pthread_mutex_lock(&lock2); //把消费者之间的锁加在信号量的里面(可取)
37 count=buf[i];
38 printf("consumer:%d,consumer data:%d\n",(int)arg,count);
39 pthread_mutex_unlock(&lock2);
40 sem_post(&blank);
41 i++;
42 i%=_SIZE_;
43 //pthread_mutex_unlock(&lock2);
44 }
45 }
46 int main()
47 {
48 pthread_mutex_init(&lock1,NULL);
49 pthread_mutex_init(&lock2,NULL);
50 pthread_t tid1,tid2,tid3,tid4;
51 sem_init(&blank,0,_SIZE_);
52 sem_init(&data,0,0);
53 pthread_create(&tid1,NULL,product,(void*)1);
54 pthread_create(&tid2,NULL,product,(void*)2);
55 pthread_create(&tid3,NULL,consumer,(void*)3);
56 pthread_create(&tid4,NULL,consumer,(void*)4);
57 pthread_join(tid1,NULL);
58 pthread_join(tid2,NULL);
59 pthread_join(tid3,NULL);
60 pthread_join(tid4,NULL);
61 pthread_mutex_destroy(&lock1);
62 pthread_mutex_destroy(&lock2);
63 sem_destroy(&blank);
64 sem_destroy(&data);
65 return 0;
66 } 运行结果:(1)把锁加在信号量的内部:
(2)把锁加在信号量的外部
本文出自 “zwy” 博客,请务必保留此出处http://10548195.blog.51cto.com/10538195/1767297
原文:http://10548195.blog.51cto.com/10538195/1767297