操作系统 生产者 - 消费者问题

简介: 操作系统 生产者 - 消费者问题

生产者 - 消费者问题

问题描述

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

记录型信号量

思路

  • 假定在生产者和消费者之间的公用缓冲池中具有n个缓冲区,这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用;利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。
  • 使用互斥信号量mutex,实现对公用缓冲池的互斥使用
  • 使用信号量empty和full代替原来的count计数,同时实现线程的同步机制
  • 利用数组buffer模拟具有n个缓冲区的缓冲池,指针in,out表示该放入缓冲区的位置,于该取走缓冲区的位置,使用 ( in / out = (in / out + 1) % n)实现循环缓冲区

image.png

代码实现

int in = 0, out = 0;  //位置记录
item buffer[n];  //缓冲池
semaphore mutex = 1;  //互斥信号量
semaphore empty = n, full = 0;  //同步信号量
void producer(){
  do{
    produce an item nextp;  //产生商品nextp
    ……
    wait(empty);  //wait的顺序不能变换
    wait(mutex);
    buffer[in] = nextp;
    in = (in + 1) % n;
    signal(mutex);
    signal(full);
  }while(TRUE);
}
void consumer(){
  do{
    wait(full);  //wait的顺序不能变换
    wait(mutex);
    nextc = buffer[out];
    out = (out + 1) % n;
    signal(mutex);
    signal(empty);
    consumer the item in nextc;
    ……
  }while(TRUE);
}
void main(){
  cobegin;  //同时开始
  producer();
  consumer();
  coend;
}

注意点

  • 互斥型信号量mutex的wait()与signal()操作一定要成对出现
  • 资源信号量empty与full的wait()与signal操作虽然不在同一进程中,但是为了实现同步,同时避免死锁一定也要对应出现
  • 一个进程中的wait()操作的次序不能颠倒,一定是先对资源信号量再对互斥信号量使用wait()

AND信号量

思路

  • 因为同时需要生产者与消费者都同时需要两个信号量的控制,故引入AND信号量
  • 使用Swait(empty,mutex)代替wait(empty),wait(mutex)
  • 使用Ssignal(mutex, full)代替signal(mutex),signal(full)
  • 同理Swait(full,mutex),Ssignal(mutex, empty)

代码实现

int in = 0, out = 0;  //位置记录
item buffer[n];  //缓冲池
semaphore mutex = 1;  //互斥信号量
semaphore empty = n, full = 0;  //同步信号量
void producer(){
  do{
    produce an item nextp;
    ……
    Swait(empty, mutex);
    buffer[in] = nextp;
    in = (in + 1) % n;
    Ssignal(mutex, full);
  }while(TRUE);
}
void consumer(){
  do{
    Swait(full, mutex);
    nextc = buffer[out];
    out = (out + 1) % n;
    Ssignal(mutex, empty);
    consumer the item in nextc;
    ……
  }while(TRUE);
}
void main(){
  cobegin;  //同时开始
  producer();
  consumer();
  coend;
}


目录
相关文章
|
Linux API 调度
实验 同步机制之生产者和消费者问题【操作系统】
实验 同步机制之生产者和消费者问题【操作系统】
277 0
|
Java
经典 生产者-消费者线程【操作系统】
经典 生产者-消费者线程【操作系统】
70 0
操作系统2020年8月生产消费者问题解析思路
操作系统2020年8月生产消费者问题解析思路
76 0
2.6操作系统(生产者消费问题 多生产者—消费者问题 吸烟者问题)
1.生产者消费问题 能否改变相邻P、V操作的顺序? 2.多生产者—消费者问题 如何实现? 可不可以不用互斥信号量? 如果盘子(缓冲区)容量为2 知识回顾与重要考点 3.吸烟者问题 如何实现
2.6操作系统(生产者消费问题 多生产者—消费者问题 吸烟者问题)
|
调度
生产者和消费者问题中的唤醒丢失(操作系统)
生产者和消费者问题中的唤醒丢失(操作系统)
169 0
|
1月前
|
安全 Linux 数据安全/隐私保护
Vanilla OS:下一代安全 Linux 发行版
【10月更文挑战第30天】
59 0
Vanilla OS:下一代安全 Linux 发行版
|
1月前
|
NoSQL Linux PHP
如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤
本文介绍了如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤。接着,对比了两种常用的 PHP Redis 客户端扩展:PhpRedis 和 Predis,详细说明了它们的安装方法及优缺点。最后,提供了使用 PhpRedis 和 Predis 在 PHP 中连接 Redis 服务器及进行字符串、列表、集合和哈希等数据类型的基本操作示例。
64 4
|
1月前
|
人工智能 安全 Linux
|
2月前
|
Unix 物联网 大数据
操作系统的演化与比较:从Unix到Linux
本文将探讨操作系统的历史发展,重点关注Unix和Linux两个主要的操作系统分支。通过分析它们的起源、设计哲学、技术特点以及在现代计算中的影响,我们可以更好地理解操作系统在计算机科学中的核心地位及其未来发展趋势。
|
4月前
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
143 3