【操作系统】c语言--使用信号量解决生产者和消费者问题

创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c++系列专栏:C/C++零基础到精通 🔥

给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ

在这里插入图片描述

c语言内容💖:

专栏:c语言之路重点知识整合

【c语言】全部知识点总结


信号量

信号量是一种同步机制,可用于保护共享资源,控制进程的访问以及协调进程之间的通信。

在生产者和消费者问题中,可以使用两个信号量:一个用于生产者,另一个用于消费者。

假设缓冲区的大小为N,生产者信号量的初始值为N,消费者信号量的初始值为0。

接下来,生产者和消费者可以使用P操作和V操作来访问缓冲区。

P操作(等待信号量):如果信号量的值为0,则进程将阻塞,直到信号量的值变为正数。如果信号量的值大于0,则进程将减少信号量的计数器并继续执行。

V操作(释放信号量):如果有进程在等待信号量,则唤醒其中一个进程。否则,信号量的计数器将增加,以表示一个资源已经可用。

分析

创建两个线程,一个用于生产者,另一个用于消费者。它们共享一个大小为5的环形缓冲区。

当生产者线程生成一个新项目时,它使用blank_number信号量将空闲空间的数量减少1,然后使用互斥变量mutex1添加到环形缓冲区中。生产者使用product_number信号量将队列项目的数量增加1。

当消费者线程消费一个项目时,它使用product_number信号量将队列项目的数量减少1,然后使用互斥变量mutex1从环形缓冲区中删除。消费者使用blank_number信号量将空余的空间数量增加1。

这种基于信号量的方法可以保证生产者和消费者之间的同步性。

  • 如果缓存区已满,则生产者线程将在blank_number信号量处阻塞,并等待直至有可用的空间。

  • 如果缓存区为空,则消费者线程将在product_number信号量处阻塞。

代码

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

#define NUM 5

int queue[NUM];                                     //全局数组实现环形队列
sem_t blank_number, product_number, mutex1;                 //空格子信号量, 产品信号量

void *producer(void *arg)
{
    int i = 0;

    while (1) {
        sem_wait(&blank_number);                    //生产者将空格子数--,为0则阻塞等待
        sem_wait(&mutex1);
        queue[i] = rand() % 1000 + 1;               //生产一个产品
        printf("----Produce---%d\n", queue[i]);
        sem_post(&mutex1);
        sem_post(&product_number);                  //将产品数++

        i = (i+1) % NUM;                            //借助下标实现环形
        sleep(rand()%3);
    }
}

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

    while (1) {
        sem_wait(&product_number);                  //消费者将产品数--,为0则阻塞等待
        sem_wait(&mutex1);
        printf("-Consume---%d\n", queue[i]);
        queue[i] = 0;                               //消费一个产品
        sem_post(&mutex1);
        sem_post(&blank_number);                    //消费掉以后,将空格子数++

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

int main(int argc, char *argv[])
{
    pthread_t pid, cid;

    sem_init(&blank_number, 0, NUM);                //初始化空格子信号量为5
    sem_init(&product_number, 0, 0);                //产品数为0
    sem_init(&mutex1, 0, 1);

    pthread_create(&pid, NULL, producer, NULL);
    pthread_create(&cid, NULL, consumer, NULL);

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

    sem_destroy(&blank_number);
    sem_destroy(&product_number);

    return 0;
}

运行结果

在这里插入图片描述


在这里插入图片描述

大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●)
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天喜Studio

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

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

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

打赏作者

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

抵扣说明:

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

余额充值