信号量实现生产者消费者

我们用条件变量和互斥量实现了生产者消费者之后,也可以试试用信号量。甚至会更加简单。

可能大家对信号量还比较陌生

1.介绍信号量

信号量与互斥量

信号量相当于初始化值为N的互斥量。

互斥量保护了共享数据,但也使并行的线程变成串行,执行效率变低了。

互斥量一次只有一个线程可以访问公共区域,信号量可以同时有N个线程访问共享数据

信号量与信号:信号量(semaphore)和信号(signal)无关,完全是两回事。O(∩_∩)O哈哈~

信号量不只能用于线程中,也可以用于进程间同步。

2.函数用法

首先sem_t sem;定义类型

 #include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);

第二个参数,0 代表线程间同步,1代表进程间同步  

value即设置初始值,指定同时访问的的线程数                                      

int sem_destroy(sem_t *sem)

sem_wait(sem_t *sem)                         

可以理解为pthread_mutex_lock

若信号量>0 ,信号量--。     若信号量为0,再调wait阻塞

sem_post(sem_t *sem)     

可以理解为pthread_mutex_unlock解锁

做信号量++操作 最多到N,再次++就会阻塞

SPSC.c

#include<stdio.h>
#include<semaphore.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>


int NUM;

sem_t blankNum,productNum;

void *producer(void *arg)
{   
    int *queue=(int *)arg;
    int i=0;
    while(1){
        sem_wait(&blankNum);//生产将blank--,为0则阻塞
        queue[i]=rand()%1000+1;
        printf("produce----%d\n",queue[i]);
        sem_post(&productNum);  //产品++
        
        i=(i+1)%NUM;        
        sleep(rand()%1);
    }    
}


void *consumer(void *arg){
    int *queue=(int *)arg;
    int i=0;
    while(1){

        sem_wait(&productNum);//消费将产品数--,为零时阻塞等待
        printf("consume----%d\n",queue[i]);
        queue[i]=0;
        sem_post(&blankNum);//将blank++

        i=(i+1)%NUM;
        sleep(rand()%3);
    }
}




int main()
{
    
    printf("The capacity is\n");
    scanf("%d",&NUM);

    int queue[NUM];//环形队列

    pthread_t pid,cid;

    sem_init(&blankNum,0,NUM);//初始时blank为NUM   
    sem_init(&productNum,0,0);//初始时产品为0

    pthread_create(&pid,NULL,producer,(void*)queue);
    pthread_create(&cid,NULL,consumer,(void*)queue);

    pthread_join(pid,NULL);
    pthread_join(cid,NULL);

    sem_destroy(&blankNum);
    sem_destroy(&productNum);

    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值