Linux 多进程生产者消费者模型实现

news2025/2/21 5:16:16

Linux 多进程生产者消费者模型实现

      • 一、模型核心组件
      • 二、关键代码解析
        • 1. 信号量封装类(csemp)
        • 2. 共享内存初始化
        • 3. 生产者核心逻辑
        • 4. 消费者核心逻辑
      • 三、关键同步机制
        • 信号量使用策略
        • 操作时序图
      • 四、扩展知识
        • 1. System V与POSIX信号量对比
        • 2. 共享内存最佳实践
        • 3. 死锁预防策略
      • 五、性能优化建议
      • 六、错误处理建议
      • 七、完整代码示例
      • 八、运行与测试

生产者消费者模型是并发编程中的经典案例,本文通过一个具体的C++示例,演示如何在Linux环境下使用System V IPC机制实现跨进程的生产者消费者模型。

一、模型核心组件

本实现采用三种关键IPC机制:

  1. 共享内存:存储循环队列数据
  2. 信号量:实现进程间同步
  3. 循环队列:数据缓冲区

二、关键代码解析

1. 信号量封装类(csemp)
class csemp {
public:
    bool init(key_t key, unsigned short value=1, short sem_flg=SEM_UNDO);
    bool wait(short sem_op=-1); // P操作
    bool post(short sem_op=1);  // V操作
    // ...其他成员函数...
};
  • SEM_UNDO标志保证进程异常终止时自动释放信号量
  • 采用RAII模式管理信号量生命周期
2. 共享内存初始化
// 获取/创建共享内存
int shmid = shmget(0x5005, sizeof(squeue<ElemType, 5>), 0640|IPC_CREAT);
// 附加到进程地址空间
squeue<ElemType, 5>* QQ = (squeue<ElemType, 5>*)shmat(shmid, 0, 0);
  • 使用固定key值0x5005标识共享内存
  • 权限设置为0640(用户读写,组读)
3. 生产者核心逻辑
mutex.wait(); // 获取互斥锁
// 数据入队操作
ee.no=3; strcpy(ee.name, "西施"); QQ->push(ee);
// ...其他数据...
mutex.post(); // 释放互斥锁
cond.post(3); // 通知消费者有3个新数据
4. 消费者核心逻辑
while(true) {
    mutex.wait();
    while (QQ->empty()) {
        mutex.post();
        cond.wait();  // 等待数据通知
        mutex.wait();
    }
    // 数据出队处理...
    mutex.post();
}

三、关键同步机制

信号量使用策略
信号量初始值作用标志位
mutex1共享内存访问控制SEM_UNDO
cond0可用数据数量通知0
操作时序图
Producer Consumer Shared Memory mutex cond wait() 写入数据 post() post(N) wait() wait() 读取数据 post() Producer Consumer Shared Memory mutex cond

四、扩展知识

1. System V与POSIX信号量对比
特性System V信号量POSIX信号量
进程间共享原生支持需要命名信号量
原子操作支持批量操作单信号量操作
持久性内核持久需显式删除
初始化灵活性需要额外控制直接初始化
2. 共享内存最佳实践
  1. 始终使用同步机制保护共享内存访问
  2. 初始化时使用双重检查锁模式
  3. 为共享内存设置合理的过期时间
  4. 使用shmdt()及时断开连接
  5. 在程序退出时使用shmctl(IPC_RMID)清理资源
3. 死锁预防策略
  • 按照固定顺序获取锁
  • 设置超时机制
  • 使用SEM_UNDO标志
  • 避免嵌套锁
  • 定期检查系统信号量状态(ipcs命令)

五、性能优化建议

  1. 批量操作优化:适当增大每次生产/消费的数据量
  2. 双缓冲区技术:使用交替缓冲区减少锁竞争
  3. 无锁队列实现:CAS原子操作替代互斥锁
  4. 内存对齐:优化共享内存访问效率
  5. 信号量分组:区分读写信号量提升并发性

六、错误处理建议

// 示例:改进的信号量初始化
bool csemp::init(key_t key, unsigned short value, short sem_flg) {
    if((m_semid = semget(key, 1, 0666)) == -1) {
        if(errno != ENOENT) {
            // 记录详细错误日志
            log_error("Semget failed: %s", strerror(errno));
            return false;
        }
        // 创建新信号量...
    }
    // ...其他初始化逻辑...
}

建议添加:

  1. 详细的错误日志记录
  2. 信号量存在性检测
  3. 自动清理僵尸信号量
  4. 重试机制(ETIMEDOUT处理)

七、完整代码示例

(此处插入用户提供的完整生产者/消费者代码)

八、运行与测试

编译执行命令:

g++ -o producer producer.cpp -lrt -pthread
g++ -o consumer consumer.cpp -lrt -pthread
./producer & ./consumer &

监控系统资源:

watch -n 1 'ipcs -s && ipcs -m'

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

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

相关文章

【Python pro】基本数据类型

一、数字类型 1.1 数字类型的组成 1.1.1 整数 &#xff08;1&#xff09;十进制&#xff0c;二进制0b&#xff0c;八进制0o&#xff0c;十六进制0x print(16 0b10000 0o20 0x10) # 输出&#xff1a;True&#xff08;2&#xff09;十进制转其他进制 a bin(16) b oct(1…

sql server查询IO消耗大的排查sql诊断语句

原文链接&#xff1a; sql server查询IO消耗大的排查sql诊断语句-S3软件[code]select top 50 (total_logical_reads/execution_count) as avg_logical_reads , (total_logical_writes/execution_count) as avg_logical_writes , (tota ... https://blog.s3.sh.cn/thread-120-1…

kubernetes源码分析 kubelet

简介 从官方的架构图中很容易就能找到 kubelet 执行 kubelet -h 看到 kubelet 的功能介绍&#xff1a; kubelet 是每个 Node 节点上都运行的主要“节点代理”。使用如下的一个向 apiserver 注册 Node 节点&#xff1a;主机的 hostname&#xff1b;覆盖 host 的参数&#xff1…

Golang学习笔记_33——桥接模式

Golang学习笔记_30——建造者模式 Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 文章目录 桥接模式详解一、桥接模式核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、桥接模式的特点三、适用场景1. 多维度变化2. 跨平台开发3. 动态切换实现 四、与其他…

【js逆向_入门】图灵爬虫练习平台 第四题

(base64解码&#xff09;地址&#xff1a;aHR0cHM6Ly9zdHUudHVsaW5ncHl0b24uY24vcHJvYmxlbS1kZXRhaWwvNC8 请求接口带有加密参数&#xff1a; 全局搜索Sign,找到参数生成位置 一目了然&#xff0c;知道参数是怎么构造生成的 调试代码 测试验证思路是否正确 时间&#xff1a; …

Mybatis后端数据库查询多对多查询解决方案

问题场景&#xff1a; 我开发的是一个论文选择系统。 后端用一个论文表paper来存储论文信息。 论文信息中&#xff0c;包含前置课程&#xff0c;也就是你需要修过这些课程才能选择这个论文。 而一个论文对应的课程有很多个。 这样就造成了一个数据库存储的问题。一个paper…

【MySQL排错 】mysql: command not found 数据库安装后无法加载的解决办法

【MySQL排错 】mysql: command not found 数据库安装后无法加载的解决办法 A Solution to Solve Error - mysql: command not found After The Installation of MySQL Community Server By JacksonML 本文简要介绍如何在macOS安装完毕MySQL数据库服务器后&#xff0c;针对无…

分享一款AI绘画图片展示和分享的小程序

&#x1f3a8;奇绘图册 【开源】一款帮AI绘画爱好者维护绘图作品的小程序 查看Demo 反馈 github 文章目录 前言一、奇绘图册是什么&#xff1f;二、项目全景三、预览体验3.1 截图示例3.2 在线体验 四、功能介绍4.1 小程序4.2 服务端 五、安装部署5.1 快速开始~~5.2 手动部…

大模型知识蒸馏技术(4)——离线蒸馏

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl离线蒸馏概述 离线蒸馏是知识蒸馏中最早被提出且最为常见的实现方式,其核心在于教师模型和学生模型的训练是分阶段进行的。具体而言,教师模型首先在训练集上进行充分训练,直至收敛,然后利用教…

解决DeepSeek服务器繁忙的有效方法

全球42%的企业遭遇过AI工具服务器过载导致内容生产中断&#xff08;数据来源&#xff1a;Gartner 2025&#xff09;。当竞品在凌晨3点自动发布「智能家居安装指南」时&#xff0c;你的团队可能正因DeepSeek服务器繁忙错失「净水器保养教程」的流量黄金期⏳。147SEO智能调度系统…

BT401双模音频蓝牙模块如何开启ble的透传,有什么注意事项

BT401音频蓝牙模块如何开启ble的透传&#xff1f; 首先BT401的蓝牙音频模块&#xff0c;分为两个版本&#xff0c;dac版本和iis数字音频版本 DAC版本&#xff1a;就是BT401蓝牙模块【9和10脚】直接输出模拟音频信号&#xff0c;也就是说&#xff0c;直接推动耳机可以听到声音 …

基于SSM框架的宠物之家系统(有源码+论文!!!)

这个系统可以帮助大家去做设计或者学习,大家可以管我要word版论文🥰这里具体论文内照片、e-r图等等加载不进来, 大家如果想要源码+论文+制定+调试,可以私信我!!(可改别的系统,例如调查问卷系统等等) 目录 第1章 绪论 1.1开发背景 1.2开发工具及语言 第2章 宠物之家系…

网工项目理论1.7 设备选型

本专栏持续更新&#xff0c;整一个专栏为一个大型复杂网络工程项目。阅读本文章之前务必先看《本专栏必读》。 一.交换机选型要点 制式:盒式交换机/框式交换机。功能:二层交换机/三层交换机。端口密度:每交换机可以提供的端口数量。端口速率:百兆/千兆/万兆。交换容量:交换矩阵…

Gateway中的Filter机制

Gateway中的Filter机制 文章目录 Gateway中的Filter机制Gateway中的Filter机制Gateway Filter 机制的概述核心思想与设计Filter 的两种类型过滤器的生命周期Gateway Filter 的特点Gateway Filter 的意义Gateway Filter 的工作原理核心架构与执行流程执行流程解析过滤器类型的角…

顺序表常用操作和笔试题

1、顺序表的常用操作 1.1 顺序表的创建 如下代码所示&#xff1a;创建了一个默认空间为10的整型顺序表&#xff0c;如果空间不足则会以1.5倍扩容。 List<Integer> list new ArrayList<>(); 创建一个空间为15的整型顺序表 List<Integer> list2 new ArrayL…

二.数据治理流程架构

1、数据治理流程架构核心思想&#xff1a; 该图描绘了一个以数据标准规范体系为核心&#xff0c;大数据生命周期管理为主线&#xff0c;数据资源中心为依托&#xff0c;并辅以数据质量管理和大数据安全与隐私管理的数据治理流程架构。它旨在通过规范化的流程和技术手段&#x…

解锁机器学习核心算法 | 线性回归:机器学习的基石

在机器学习的众多算法中&#xff0c;线性回归宛如一块基石&#xff0c;看似质朴无华&#xff0c;却稳稳支撑起诸多复杂模型的架构。它是我们初涉机器学习领域时便会邂逅的算法之一&#xff0c;其原理与应用广泛渗透于各个领域。无论是预测房价走势、剖析股票市场波动&#xff0…

CSS 底部颗粒磨砂特效

参考&#xff1a;element-plus的顶部效果 background-image: radial-gradient(transparent 1px, var(--bg-color) 1px); background-size: 4px 4px; backdrop-filter: saturate(50%) blur(4px); 注意点&#xff1a;var(--bg-color) 改为跟你背景色相同的即可。 其他自己看情况…

QT自定义扫描控件,支持任意方位拖动和拖动扫描范围。

部分代码&#xff1a; void FishControlForm::paintEvent(QPaintEvent *event) {QPainter p(this);p.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);p.translate(m_centerPoint);//bgp.setPen(Qt::white);p.drawEllipse(-m_radius,-m_radius,m_rad…

Ubuntu18.04安装rvm、ruby2.6.5和rails5.2.6

系统环境&#xff1a;Ubuntu 18.04 一、安装前准备 1. sudo apt update 2. sudo apt upgrade 如果提示abort&#xff0c;忽略。 3. sudo apt install sqlite3 gnupg curl git libpq-dev 二、安装rvm ruby版本管理器 1.切换管理员模式 sudo su 2.安装软件签名公钥 gpg…