信号量实现生产者消费者程序_C语言示例

信号量的基本思想是通过一个计数器和一组相关的操作来实现资源的控制和同步。计数器表示可用的资源数量,每次访问共享资源时,线程需要先申请信号量,如果信号量的计数器大于零,则线程可以访问共享资源并将计数器减一;如果计数器为零,则线程需要等待,直到其他线程释放资源,使计数器变为非零。
信号量和线程锁Mutex有很多相似之处,也有些不同点:
①Mutex只能是0和1,0表示上锁,1表示释放锁。但是semaphore可以大于1。
②信号量可以用于线程间,也可以用于进程间通信。但是Mutex只能用于线程间通信。
主要有以下几个函数:

int sem_init (sem_t *sem, int pshared, unsigned int value);//初始化信号量
int sem_wait(sem_t *sem); //阻塞等,等不到就一直阻塞着等
int sem_trywait(sem_t *sem); //非阻塞等
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); //定时等

生产者消费者模型如下:
创建个仓库,里面有5个空位,可以放0-5件商品。
如果放满了没人来取商品,就是爆仓
如果取货时没货,就是崩盘

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#define _POSIX_C_SOURCE 200809L
#include <semaphore.h>

#define NUM 5

int q[NUM];//仓库,最多能放5件物品

sem_t* blank_number;
sem_t* goods_number;

void* producer(void* arg)
{
    int i = 0;
    while(1)
    {
        sem_wait(blank_number);//抢空位,抢不到就一直等
        q[i] = rand() % 100 + 1;
        printf("produce %d\n", q[i]);
        sem_post(goods_number); //增加一个商品
        i = (i + 1) % NUM;
        sleep(rand()%3); //每次休息1-3秒钟
    }
}

void* consumer(void *arg)
{
    int i = 0;
    while(1)
    {
        sem_wait(goods_number);//抢商品,抢不到就阻塞
        printf("consume %d\n", q[i]);
        q[i] = 0; //消费掉这个商品
        sem_post(blank_number);//释放一个空位
        i = (i + 1) % NUM;
        sleep(rand() % 3); //每次休息1-3秒钟
    }
}

int main()
{
//使用time(NULL)函数返回的当前时间作为种子,然后传递给srand函数,以初始化伪随机数生成器。
//通常情况下,如果不给伪随机数生成器提供一个种子,那么每次程序运行时生成的随机数都是相同的。
    srand(time(NULL));

//下面2行是Linux的写法
    // sem_init(blank_number, 0, NUM); //空位,0表示单进程多线程,一开始5个空位
    // sem_init(blank_number, 0, 0); //产品,0表示单进程多线程,一开始0个商品

//下面2行是mac的写法
    blank_number = sem_open("blank_number", O_CREAT, S_IRUSR | S_IWUSR, NUM);
    goods_number = sem_open("goods_number", O_CREAT, S_IRUSR | S_IWUSR, 0);

    pthread_t pid, cid;//生产者ID和消费者ID
    pthread_create(&pid, NULL, producer, NULL); //起生产者线程
    pthread_create(&cid, NULL, consumer, NULL); //起消费者线程

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

    return 0;
}

结果是:

zhanghaodeMacBook-Pro:cpp_excise zhanghao$ ./a.out 
produce 96
produce 85
consume 96
consume 43
consume 18
produce 4
produce 56
produce 64
produce 81
^C

注:这个代码,可以检测到崩盘:消费如果为0,说明当前没货,就崩盘了。但爆仓检测不到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码到程攻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值