該信號量是POSIX版本的。是用於線程間同步與互斥的。和進程間的信號量類似,都是管理臨界資源的,都有P、V操作,只不過它的P、V操作是用下面的函數接口實現的
int sem_wait(sem_t *sem);P操作 資源 -1;申請資源
int sem_post(sem_t *sem);V操作 資源 +1;釋放資源
1 #include<stdio.h>
2 #include<pthread.h>
3 #include<semaphore.h>
4 #include<stdlib.h>
5 #define _SIZE_ 20
6 static int i = 0;
7 sem_t block;
8 sem_t data;
9 pthread_mutex_t lock1;
10 pthread_mutex_t lock2;
11 int buf[_SIZE_];
12 void *product(void *arg)
13 {
14 //int i = 0;
15 int index = 0;
16 while(1)
17 {
18 //pthread_mutex_lock(&lock1);
19 sem_wait(&block);
20 pthread_mutex_lock(&lock1);
21 printf("product%d is done...\n",(int)arg);
22 buf[index] = i++;
23 index = index%_SIZE_;
24 pthread_mutex_unlock(&lock1);
25 sem_post(&data);
26 //pthread_mutex_unlock(&lock1);
27 sleep(1);
28 }
29 }
30 void *consumer(void *arg)
31 {
32 int index = 0;
33 while(1)
34 {
35 //pthread_mutex_lock(&lock2);
36 sem_wait(&data);
37 pthread_mutex_lock(&lock2);
38 printf("consumer%d is done :%d\n",(int)arg,buf[index]);
39 index = index%_SIZE_;
40 pthread_mutex_unlock(&lock2);
41 sem_post(&block);
42 //pthread_mutex_unlock(&lock2);
43 sleep(1);
44 }
45 }
46
47 int main()
48 {
49 pthread_t tid1,tid2,tid3,tid4;
50 pthread_create(&tid1,NULL,product,(void*)1);
51 pthread_create(&tid2,NULL,product,(void*)2);
52 pthread_create(&tid3,NULL,consumer,(void*)1);
53 pthread_create(&tid4,NULL,consumer,(void*)2);
54
55 pthread_mutex_init(&lock1,NULL);
56 pthread_mutex_init(&lock2,NULL);
57
58 sem_init(&block,0,20);
59 sem_init(&data,0,0);
60
61 sem_destroy(&block);
62 sem_destroy(&data);
63
64 pthread_join(tid1,NULL);
65 pthread_join(tid2,NULL);
66 pthread_join(tid3,NULL);
67 pthread_join(tid4,NULL);
68
69 pthread_mutex_destroy(&lock1);
70 pthread_mutex_destroy(&lock2);
71 return 0;
72 }
運行結果:
[fbl@localhost sem]$ ./my_sem
product2 is done...
consumer1 is done :0
product1 is done...
consumer2 is done :1
product2 is done...
consumer1 is done :2
product1 is done...
consumer2 is done :3
product2 is done...
consumer1 is done :4
product1 is done...
consumer2 is done :5
product2 is done...
consumer1 is done :6
product1 is done...
consumer2 is done :7
product2 is done...
consumer1 is done :8
product1 is done...
上述代碼我們把互斥鎖加在了P、V操作裏面。是因爲P、V操作本身是原子的,不必擔心會有兩個線程同時訪問的情況發生。