Linux 多线程 生产者消费者 问题

在 Linux 系统中,生产者和消费者问题是一个经典的多线程同步问题,用于描述如何在多线程环境中协调多个线程对共享资源的访问。这个问题通常涉及两个类型的线程:生产者线程和消费者线程。生产者线程负责生成数据并将其放入缓冲区,而消费者线程则从缓冲区中取出数据进行处理。

生产者和消费者问题的基本概念

  1. 生产者(Producer):

    • 生成数据并将其放入共享缓冲区。
    • 生产者必须在缓冲区满时等待,直到有空间可用。
  2. 消费者(Consumer):

    • 从共享缓冲区中取出数据进行处理。
    • 消费者必须在缓冲区空时等待,直到有数据可用。

共享资源和同步机制

为了确保线程安全并避免竞态条件,生产者和消费者通常使用以下同步机制:

  1. 互斥锁(Mutex):

    • 用于确保只有一个线程可以在任何给定时间内访问共享缓冲区。
    • 通过锁定和解锁操作来实现。
  2. 条件变量(Condition Variable):

    • 用于让线程在某些条件下等待或唤醒。
    • 生产者在缓冲区不满时发信号唤醒消费者,消费者在缓冲区有数据时发信号唤醒生产者。

让我们用一个更生动的例子来解释生产者-消费者问题中的条件变量和互斥锁的工作机制。

例子:餐厅的厨师和服务员

想象一下,有一个餐厅,里面有一个厨房(缓冲区)和一个用餐区。餐厅有两种工作人员:厨师(生产者)和服务员(消费者)。他们之间的协调就像在处理生产者-消费者问题。

场景设置
  • 厨房有一个有限大小的桌子(缓冲区),桌子上可以放一定数量的菜(数据)。
  • 厨师做菜(生产数据)并把菜放到桌子上。
  • 服务员从桌子上拿菜(消费数据)并把菜送到顾客那里。
  • 如果桌子满了,厨师就不能放菜,需要等待服务员拿走菜。
  • 如果桌子空了,服务员就不能拿菜,需要等待厨师放菜。
具体流程
  1. 厨师做菜并放在桌子上:

    • 厨师首先检查桌子上有没有空位。
    • 如果桌子满了,厨师就等待(进入等待状态)。
    • 如果桌子有空位,厨师把菜放在桌子上,然后通知服务员桌子上有新菜了。
    • 厨师然后继续做下一道菜。
  2. 服务员拿菜并送到顾客那里:

    • 服务员首先检查桌子上有没有菜。
    • 如果桌子空了,服务员就等待(进入等待状态)。
    • 如果桌子上有菜,服务员拿走菜并送到顾客那里,然后通知厨师桌子上有空位了。
    • 服务员然后继续拿下一道菜。

代码对应的具体场景

以下代码片段展示了这个过程:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#define BUFFER_SIZE 10int buffer[BUFFER_SIZE];
int count = 0;pthread_mutex_t mutex;
pthread_cond_t cond_producer;
pthread_cond_t cond_consumer;void* producer(void* arg) {while (1) {// 生成数据(例如:随机数)int item = rand() % 100;pthread_mutex_lock(&mutex);// 等待缓冲区有空位while (count == BUFFER_SIZE) {pthread_cond_wait(&cond_producer, &mutex);}// 将数据放入缓冲区buffer[count++] = item;printf("Produced: %d\n", item);// 通知消费者有数据可用pthread_cond_signal(&cond_consumer);pthread_mutex_unlock(&mutex);// 模拟生产时间sleep(1);}
}void* consumer(void* arg) {while (1) {pthread_mutex_lock(&mutex);// 等待缓冲区有数据while (count == 0) {pthread_cond_wait(&cond_consumer, &mutex);}// 从缓冲区取出数据int item = buffer[--count];printf("Consumed: %d\n", item);// 通知生产者有空位可用pthread_cond_signal(&cond_producer);pthread_mutex_unlock(&mutex);// 模拟消费时间sleep(1);}
}int main() {pthread_t producer_thread, consumer_thread;pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond_producer, NULL);pthread_cond_init(&cond_consumer, NULL);pthread_create(&producer_thread, NULL, producer, NULL);pthread_create(&consumer_thread, NULL, consumer, NULL);pthread_join(producer_thread, NULL);pthread_join(consumer_thread, NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond_producer);pthread_cond_destroy(&cond_consumer);return 0;
}

运行结果:

解释
  1. 互斥锁(pthread_mutex_t mutex)

    • 互斥锁就像厨房的门,确保只有一个厨师或服务员可以进出厨房,以防止混乱。
  2. 条件变量(pthread_cond_t cond_producer 和 pthread_cond_t cond_consumer)

    • 条件变量就像门口的信号灯。
    • cond_producer 是厨师用来等待服务员拿走菜的信号灯。
    • cond_consumer 是服务员用来等待厨师放菜的信号灯。
  3. 厨师(producer)

    • 厨师检查厨房的桌子(缓冲区)是否满了。
    • 如果满了,厨师等待(等待cond_producer信号)。
    • 如果有空位,厨师放菜在桌子上,并通知服务员(发送cond_consumer信号)。
    • 然后,厨师离开厨房(解锁互斥锁),继续做下一道菜。
  4. 服务员(consumer)

    • 服务员检查厨房的桌子(缓冲区)是否有菜。
    • 如果桌子空了,服务员等待(等待cond_consumer信号)。
    • 如果有菜,服务员拿走菜,并通知厨师(发送cond_producer信号)。
    • 然后,服务员离开厨房(解锁互斥锁),继续送菜给顾客。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/22731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3D开发工具HOOPS助力PLM/PDM系统创新,高效实现复杂数据精细处理、3D模型交互可视化!

在现代制造和工程领域&#xff0c;PLM&#xff08;产品生命周期管理&#xff09;和PDM&#xff08;产品数据管理&#xff09;已成为企业优化流程和提升竞争力的关键工具。 随着技术的飞速发展&#xff0c;PLM和PDM应用程序需要更先进的工具来处理复杂的CAD数据、实现高效的3D可…

九泰智库-注册讲堂 | 浙江省eRPS系统上线后提交文件要求

浙械eRPS系统(https://ylqx.certca.cn/ylqxonline/)已正式上线启用。 在过渡期内&#xff0c;注册申请人需要同时进行线上医疗器械注册电子申报和提交纸质资料&#xff0c;以确保审评审批工作的顺利进行。过渡期结束时间另行通知。 以下是对电子申报资料格式要求的总结&#…

从零开始:如何通过美颜SDK构建自己的直播美颜工具

今天&#xff0c;我将详细介绍如何通过美颜SDK从零开始构建自己的直播美颜工具。 一、了解美颜SDK 什么是美颜SDK 开发者可以通过集成SDK&#xff0c;快速在应用中实现这些功能&#xff0c;而无需从头编写复杂的图像处理算法。 选择合适的美颜SDK 选择时可以根据以下几个方…

南京观海微电子-----555函数信号发生器电路分析

电路图 整个电路的工作过程&#xff1a; 首先&#xff0c;555芯片通过外围电阻电容组成一个多谐振荡器&#xff0c;输出一个方波。 555多谐振荡器输出方波后&#xff0c;经电容C1耦合到由R3&#xff0c;C3组成的积分网络。输出三角波。这也是一个电容充放电的过程&#xff0c…

学生问的一道CSS3媒体查询,实现响应式设计的题

目录 题目要求&#xff1a; 解题思路&#xff1a; 解题&#xff1a; 1&#xff09;大屏、3个DIV水平排列 2&#xff09;中屏、前2个DIV水平占一半&#xff0c;第三个另起一行&#xff0c;宽度占满 3&#xff09;小屏&#xff0c;3个DIV铺满&#xff0c;垂直排列 题目要求&…

2024年端午节放假通知

致尊敬的客户以及全体同仁&#xff1a; 2024年端午节将至&#xff0c;根据国务院办公厅通知精神&#xff0c;结合公司的实际情况&#xff0c;现将放假事宜通知如下&#xff1a; 2024年6月8日&#xff08;星期六&#xff09;至6月10日&#xff08;星期一&#xff09;&#xff…

科普丨什么是数字孪生灌区(平台)?如何建设?有何好处?

在农业发展的新时代&#xff0c;数字孪生灌区的概念逐渐走进大众视野&#xff0c;成为推动农业现代化、提升粮食安全保障能力的关键力量。那么&#xff0c;究竟什么是数字孪生灌区&#xff1f;它又是如何建设的&#xff1f;又能为我们带来哪些好处呢&#xff1f; 数字孪生灌区…

Java基础教程 - 10 异常

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 10 异常 10.1 异常的概念 什么是异常&#xff1f; 异常&#xff08;Exceptions&#xff09;是指在程序执行过程中出现的错误或异常情况&#xff0c;导致程序无法继续正常执行的事件。 但是…

R_AARCH64_ADR_PREL_PG_HI21问题说明

目录 问题现象&#xff1a; 问题原因 问题机理 问题现象&#xff1a; 客户现场加载out文件出现如下问题&#xff1a; 打印“Relocation of type ‘R_AARCH64_ADR_PREL_PG_HI22…..’”,明确是ARDP指令引起的问题 问题原因 ARDP的寻址范围是4GB范围&#xff0c;加载的位置…

Linux C语言学习:数据类型

一、 为什么要引入数据类型 • 计算机中每个字节都有一个地址&#xff08;类似门牌号&#xff09; • CPU通过 地址 来访问这个字节的空间 0x20001103 1 0 0 1 0 0 1 1 0x20001102 1 1 1 0 1 1 1 0 0x20001101 1 1 1 1 0 1 0 1 0x20001100 0 …

密码学基本概念(补充)

BiBa模型的*特性规则&#xff1a;主体不能修改更高完整级的客体&#xff08;主题不能向上写&#xff09; Diffie-Hellman密钥交换协议的安全性基于求解离散对数的困难性&#xff0c;既对于C^d M mod P&#xff0c;在已知C和P的前提下&#xff0c;由d求M很容易&#xff0c;但是…

Transformer系列:图文详解KV-Cache,解码器推理加速优化

前言 KV-Cache是一种加速Transformer推理的策略&#xff0c;几乎所有自回归模型都内置了KV-Cache&#xff0c;理解KV-Cache有助于更深刻地认识Transformer中注意力机制的工作方式。 自回归推理过程知识准备 自回归模型采用shift-right的训练方式&#xff0c;用前文预测下一个…

EditPlus 输入错误: 没有文件扩展“.js”的脚本引擎

原因 JS扩展名的文件被其他软件关联了&#xff0c;需要取消关联 解决办法 cmd窗口&#xff0c;输入 regedit 进入注册表&#xff0c; 打开注册表编辑器&#xff0c;定位[HKEY_CLASSES_ROOT\.js]这一项&#xff0c;双击默认值将其改为“JSFile”即可

Codeforces Round 948 (Div. 2) A~D

A. Little Nikita &#xff08;思维&#xff09; 题意&#xff1a; 小 A A A决定用一些立方体建一座塔。一开始&#xff0c;塔上没有任何立方体。在一次移动中&#xff0c;小 A A A要么正好把 1 1 1 个立方体放到塔顶&#xff0c;要么正好从塔顶移走 1 1 1 个立方体。存不存…

信息可溯、安全可控 | SW-LIMS 采测分离监测模式解析

数据的准确性在环境监测过程中至关重要,为了确保环监数据的真实有效,并满足“全程留痕、全程监控、信息可溯、安全可控”的要求,采测分离监测模式是一个有效的解决方案。 这种模式通过将样品采集和样品检测交由不同的单位完成,形成了相互独立、相互监督的工作机制,有助于减少潜…

LeetCode刷题之HOT100之跳跃游戏

2024/6/5 今天下起了绵密细雨&#xff0c;空气清新很多。昨晚做的梦较魔幻&#xff0c;可能也是导致我睡觉时业已破损的小米手环8的表腕断裂的因素之一。来到实验室&#xff0c;打扫一下卫生&#xff0c;听听歌&#xff0c;做道题。好不自在呀&#xff01; 1、题目描述 2、逻辑…

mysql中optimizer trace的作用

大家好。对于MySQL 5.6以及之前的版本来说&#xff0c;查询优化器就像是一个黑盒子一样&#xff0c;我们只能通过EXPLAIN语句查看到最后 优化器决定使用的执行计划&#xff0c;却无法知道它为什么做这个决策。于是在MySQL5.6以及之后的版本中&#xff0c;MySQL新增了一个optimi…

我国液碱产量逐渐增长 行业集中度有望不断提升

我国液碱产量逐渐增长 行业集中度有望不断提升 液碱是由氢氧化钠&#xff08;NaOH&#xff09;、氢氧化钾&#xff08;KOH&#xff09;等化合物以及水组成的一种碱性化合物。液碱的相对分子质量为40.00&#xff0c;密度为1.318g/cm&#xff0c;在常温常压下多表现为一种无色、无…

12 - 常用类

那就别跟他们比&#xff0c;先跟自己比&#xff0c;争取今天比昨天强一些&#xff0c;明天比今天强一些。 1.包装类 针对八种基本数据类型封装的相应的引用类型。 有了类的特点&#xff0c;就可以调用类中的方法。&#xff08;为什么要封装&#xff09; 基本数据类型包装类b…

JavaSE——学习总结

一、初识Java 运行Java程序 Java是一门半编译型、半解释型语言 先通过javac编译程序把源文件进行编译&#xff0c;编译后生成的.class文件是由字节码组成的&#xff0c;和平台无关、面向JVM的文件&#xff0c;最后启动java虚拟机来运行.class文件&#xff0c;此时JVM会将字节…