线程同步之信号量

信号量的头文件 #include<semaphore.h>

信号量不像条件变量那样不是锁,信号量是锁,是互斥锁的加强版。

pthread_mutex_t mutex;这个互斥锁lock(),mutex == 0,unlock(),mutex==1;线程间访问共享资源是串行的。

信号量 sem_t sem; 信号量设置的初始值可以不为1,假设一开始设置信号零的初始值为3;

当第一个线程访问共享资源,那sem的值减一等于2,第二个线程访问共享资源的话在减一等于1,第三个线程访问共享资源在减一等于0,那此时,如果这三个线程都还没有解锁,那么就会阻塞,直到有一个线程解锁信号量加一,下一个线程才可以访问共享资源,这三个访问共享资源的线程是并行访问的,相比于互斥锁而言,提高了效率。

1.信号量类型
            sem_t sem;
            加强版的互斥锁
 2.主要函数
            初始化信号量
                sem_init(sem_t *sem,int pshared,unsigned int value);
                    0 线程同步
                    1 进程同步
                    value 最多有几个线程操作共享数据
            销毁信号量
                sem_destroy(sem_t* sem);
            加锁--
                sem_wait(sem_t *sem);
                    调用一次相当于sem做了一次--操作
                    如果sem值为0,线程会阻塞
            尝试加锁
                sem_trywait(sem_t * sem);
                    sem == 0,加锁失败,不会阻塞,直接返回
            限时尝试加锁
                sem_timedwait(sem_t *sem,xxxx);
            解锁++
                sem_post(sem_t* sem);
                释放资源,对sem++

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<pthread.h>
  4 #include<string.h>
  5 #include<semaphore.h>
  6 
  7 //定义两个信号量
  8 sem_t producer_sem;
  9 sem_t customer_sem;
 10 
 11 //定义节点
 12 typedef struct Node
 13 {
 14     int data;
 15     struct Node *next;
 16 }Node;
 17 
 18 Node *head = NULL;
 19 void* producer()
 20 {
 21     while(1)
 22     {
 23         //一开始,生产者要生产,所以信号量减一
 23         //一开始,生产者要生产,所以信号量减一
 24         sem_wait(&producer_sem);   //--
 25         Node *p = (Node *)malloc(sizeof(Node));
 26         p->data = rand()%1000;
 27         p->next = head;
 28         head = p;
 29         printf("producer = %d\n",head->data);
 30         //当生产完成之后,需要提醒消费者可以消费了,也释放自己占用的信号量
 31         sem_post(&customer_sem);   //++
 32         sleep(rand()%3);
 33     }
 34 
 35     return NULL;
 36 }
 37 
 38 void *customer()
 39 {
 40     while(1)
 41     {
 42         //当信号量不是0的时候,消费者就可以访问共享资源,占用一个信号量,信>    号量减一
 43         sem_wait(&customer_sem);  //--
 44 
 45         Node *p = head->next;
 46         printf("customer = %d\n",head->data);
 47         free(head);
 48         head = p;
 49         //用完之后释放解锁,提醒生产者有多余的信号量,
 50         sem_post(&producer_sem);   //++
 51         sleep(rand()%3);
 52     }
 53 }
 54 
 55 
 56 int main()
 57 {
 58     pthread_t p1,p2;
 59     //创建两个线程
 60     pthread_create(&p1,NULL,producer,NULL);
 61     pthread_create(&p2,NULL,customer,NULL);
 62 
 63     //初始化生产者信号量,有四个线程操作共享资源
 64     sem_init(&producer_sem,0,4);
 65     //初始化消费者信号量,一开始没有资源,所以消费者一开始阻塞
 66     sem_init(&customer_sem,0,0);
 67 
 68 
 69     //释放信号狼
 70     sem_destroy(&producer_sem);
 71     sem_destroy(&customer_sem);
 72 
 73 
 74 
 75     //等待回收线程
 76     pthread_join(p1,NULL);
 77     pthread_join(p2,NULL);
 78 
 79     return 0;
 80 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值