system V信号量只能用于进程,而POSIX信号量既可以用于进程也可以用于线程
POSIX信号量统计临界资源的计数器
POSIX信号量和system V信号量的相同作用:用于同步操作,达到无冲突的访问共享资源目的
初始化信号量
参数:sem ——要初始化的信号量
pshared——0表示线程间共享,非零表示进程间共享
value——信号量初始值
返回值:成功返回0,失败返回-1
销毁信号量
参数:sem——要销毁的信号量
返回值:成功返回0,失败返回-1
等待信号量(P操作)
功能:等待信号量,会将信号量的值减1
返回值:成功返回0,失败返回-1
发布信号量(V操作)
功能:发布信号量,表示资源使用完毕,可以归还资源。将信号量的值加1
返回值:成功返回0,失败返回-1
由于我们编写的是多生产者多消费者模型,所以我们还需要维持生产者与生产者之间的互斥关系,还有消费者与消费者之间的互斥关系,同样的我们需要用到互斥量
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<pthread.h>
4 #include<sys/types.h>
5 #include<semaphore.h>
6
7 #define M 10
8 #define C 3
9 #define P 3
10 int ring[M];//环形队列,利用数组和%运算实现
11
12 sem_t sem_data;//数据量
13 sem_t sem_blank;//空格子数量
14
15 pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;//消费者之间的互斥
16 pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;//生产者之间的互斥
17
18 //消费者
19 void* runC(void *arg)
20 {
21 static int i = 0;
22 int d;
23 while(1){
24 pthread_mutex_lock(&lock1);//加锁,必须给临界区的所有代码加锁
25 sem_wait(&sem_data);//消费者申请数据资源
26 d = ring[i];
27 printf("consumer data: %d\n",d);
28 i++;
29 i %= M;//模运算,防止下标越界
30 sem_post(&sem_blank);//消费数据后对空格资源V操作
31 pthread_mutex_unlock(&lock1);//解锁
32 sleep(3);
33 }
34 }
35 //生产者
36 void* runP(void *arg)
37 {
38 int data = 0;
39 static int i = 0;
40 while(1){
41 pthread_mutex_lock(&lock2);//加锁
42 data = rand()%100 + 1;
43 sem_wait(&sem_blank);//生产者申请空格资源
44 ring[i] = data;
45 printf("product data: %d\n",data);
46 i++;
47 i %= M;//模运算,防止下标越界
48 sem_post(&sem_data);//生产者生产完数据后对数据资源V操作
49 pthread_mutex_unlock(&lock2);//解锁
50 sleep(3);
51 }
52 }
53
54 int main()
55 {
56 srand((unsigned long)time(NULL));
57
58 pthread_t consumer[C];
59 pthread_t product[P];
60
61 int i = 0;
62 for(i = 0;i < C;i++)//创建多个消费者线程
63 {
64 pthread_create(&consumer[i],NULL,runC,NULL);
65 }
66 for(i = 0;i < P;i++)//创建多个生产者线程
67 {
68 pthread_create(&product[i],NULL,runP,NULL);
69 }
70
71 sem_init(&sem_data,0,0);
72 sem_init(&sem_blank,0,M);
73
74 for(i = 0;i < C;i++)
75 {
76 pthread_join(consumer[i],NULL);
77 }
78 for(i = 0;i < P;i++)
79 {
80 pthread_join(product[i],NULL);
81 }
82
83 sem_destroy(&sem_data);
84 sem_destroy(&sem_blank);
85
86 pthread_mutex_destroy(&lock1);
87 pthread_mutex_destroy(&lock2);
88
89 return 0;
90 }