该信号量是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操作本身是原子的,不必担心会有两个线程同时访问的情况发生。