线程同步之信号量

信号量是进化版的互斥锁(互斥锁,加锁后由1变为0就会阻塞,而信号量是由N变成N--,只要不是0,就不会阻塞)

N等于1的话,信号量就与互斥锁等价了。

互斥锁的粒度比较大,无法在多个线程间对某一对象的部分数据进行共享,降低了线程的并发性,信号量可以解决这个问题

1、信号量常用的函数(函数前缀没有pthread,故信号量也可以用于进程同步)

#include <semaphore.h>

1)sem_init

 pshared:=0,用于线程间同步;

pshared>0,用于进程间同步。

2)sem_destroy//有init就对应有destroy.

3)sem_wait//相当于pthread_mutex_lock;N--

4)sem_trywait

5)sem_post//相当于pthread_mutex_unlock;N++

信号量大于0,则信号量--

信号量等于0,则造成线程阻塞。

信号量的初值,决定了占用信号量线程的个数。

2、信号量生产者和消费者模型

定义两个信号量sem_productor、sem_t sem_blank;

生产者

产品数:sem_productor;

sem_wait(&sem_blank);//N--                                   //想象成停车位,等到车位了,剩余车位-1(信号量-1)

sem_post(&sem_productor);//N++                         //想象成停车位,车离开车位了,剩余车位+1(信号量+1)

消费者:

空格数sem_t sem_blank;

sem_wait(&sem_productor);//N--

sem_post(&sem_blank);//N++

#inlcude <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <semphore.h>
#define NUM 5
sem_t product_number,blank_number;
int queue[NUM];

void *productor(void*arg)
{
    int i =0;
    while(1)
    {
        sem_wait(&blank_number);//空格子数--,为0阻塞
        queue[i] = rand()%1000+1;
        printf("productor%d",queue[i]);
        sem_post(&product_number);//产品数++
        i = (i+1)%NUM;//实现环形队列
        sleep(rand()%3);
    }
 }
void *consumer(void*arg)
{
    int i =0;
    while(1)
    {
        sem_wait(&product_number);
        queue[i] = 0;
        printf("consumer%d",queue[i]);
        sem_post(&blank_number);
        i = (i+1)%NUM;
        sleep(rand()%3);
    }
 }
void main()
{
    sem_init(&product_number,0,0);//初始化产品数为0
    sem_init(&blank_number,0,NUM);//初始化空格为5
    pthread_t pthread_p,pthread_c;
    pthread_create(&pthread_p,NULL,productor,NULL);
    pthread_create(&pthread_c,NULL,consumer,NULL);
    pthread_join(pthread_p,NULL);
    pthread_join(pthread_c,NULL);
    sem_destroy(&product_number);
    sem_destroy(&blank_number);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值