新闻详情

新闻详情

首页 / 资讯中心 / 详情

【操作系统实验】Linux 下多线程同步与互斥实战——生产者 - 消费者模型

发布时间:2026/9/4 3:38:06来源:尧图网络
【操作系统实验】Linux 下多线程同步与互斥实战——生产者 - 消费者模型
摘要本文记录了在 Ubuntu Linux 环境下使用 GCC 和 POSIX 线程库pthread解决经典并发编程问题——“生产者 - 消费者问题”的全过程。文章详细分析了信号量Semaphore与互斥锁Mutex的配合机制并提供了完整的可运行代码及编译调试步骤。对于正在学习操作系统课程的同学这是一份实用的参考指南。一、前言最近在进行操作系统的课程设计核心任务是理解进程 / 线程间的同步与互斥机制。经典的“生产者 - 消费者问题”是理解这一概念的基石。我的开发环境是在 Windows 宿主机上通过VMware Workstation运行的Ubuntu 64 位虚拟机。这种环境既能保证系统的安全性又能提供原汁原味的 Linux 命令行体验非常适合进行底层系统编程的学习。二、问题分析在这个实验中我们需要模拟多个生产者和多个消费者共享一个固定大小的缓冲区生产者Producer负责生产数据并放入缓冲区。如果缓冲区满了必须等待。消费者Consumer负责从缓冲区取出数据。如果缓冲区空了必须等待。互斥访问无论生产还是消费同一时刻只能有一个线程操作缓冲区以防止数据错乱。为了实现上述逻辑我们需要三个关键的同步工具mutex互斥锁保护缓冲区的互斥访问。empty信号量记录空闲缓冲区的数量初始值为缓冲区总大小 $M$。full信号量记录已填充数据的缓冲区数量初始值为 $0$。三、核心代码实现以下是我在 Ubuntu 终端中编写并验证通过的完整代码producer_consumer.c。代码使用了semaphore.h和pthread.h库。#include stdio.h #include stdlib.h #include unistd.h #include pthread.h #include semaphore.h #define BUFFER_SIZE 5 // 缓冲区大小 M #define PRODUCER_NUM 2 // 生产者数量 #define CONSUMER_NUM 2 // 消费者数量 int buffer[BUFFER_SIZE]; int in 0; // 生产者写入位置 int out 0; // 消费者读取位置 // 定义信号量和互斥锁 sem_t empty_sem; sem_t full_sem; pthread_mutex_t mutex; // 生产者函数 void *producer(void *arg) { int id *(int *)arg; while (1) { sleep(1); // 模拟生产耗时 sem_wait(empty_sem); // P(empty): 申请空位 pthread_mutex_lock(mutex); // Lock: 进入临界区 // --- 写入数据 --- buffer[in] 1; printf([生产者 %d] 放入数据到位置 %d\n, id, in); in (in 1) % BUFFER_SIZE; pthread_mutex_unlock(mutex); // Unlock: 离开临界区 sem_post(full_sem); // V(full): 增加满位计数 } return NULL; } // 消费者函数 void *consumer(void *arg) { int id *(int *)arg; while (1) { sleep(2); // 模拟消费耗时 sem_wait(full_sem); // P(full): 申请数据 pthread_mutex_lock(mutex); // Lock: 进入临界区 // --- 读取数据 --- printf([消费者 %d] 从位置 %d 取出数据\n, id, out); buffer[out] 0; out (out 1) % BUFFER_SIZE; pthread_mutex_unlock(mutex); // Unlock: 离开临界区 sem_post(empty_sem); // V(empty): 增加空位计数 } return NULL; } int main() { pthread_t prod_threads[PRODUCER_NUM], cons_threads[CONSUMER_NUM]; int prod_ids[PRODUCER_NUM], cons_ids[CONSUMER_NUM]; // 初始化 sem_init(empty_sem, 0, BUFFER_SIZE); sem_init(full_sem, 0, 0); pthread_mutex_init(mutex, NULL); // 创建线程 for (int i 0; i PRODUCER_NUM; i) { prod_ids[i] i; pthread_create(prod_threads[i], NULL, producer, prod_ids[i]); } for (int i 0; i CONSUMER_NUM; i) { cons_ids[i] i; pthread_create(cons_threads[i], NULL, consumer, cons_ids[i]); } // 等待线程结束此处为死循环演示实际需配合退出逻辑 for (int i 0; i PRODUCER_NUM; i) pthread_join(prod_threads[i], NULL); for (int i 0; i CONSUMER_NUM; i) pthread_join(cons_threads[i], NULL); // 销毁资源 sem_destroy(empty_sem); sem_destroy(full_sem); pthread_mutex_destroy(mutex); return 0; }四、编译与运行指南在 Ubuntu 虚拟机中请按照以下步骤操作保存文件将上述代码保存为producer_consumer.c。编译命令注意需要链接pthread库。gcc producer_consumer.c -o pc_demo -lpthread运行程序./pc_demo观察输出你会看到生产者和消费者交替打印日志且不会出现缓冲区溢出或读取空数据的情况。按CtrlC终止程序。五、实验心得与注意事项P/V 操作顺序至关重要在生产者中必须先wait(empty)再lock(mutex)在消费者中必须先wait(full)再lock(mutex)。如果顺序反了先锁后等信号量极易导致死锁。编译报错处理如果在 Ubuntu 上编译提示找不到semaphore.h请确保安装了libc6-dev包通常默认已安装。虚拟机的优势如果在实验中不小心写错了代码导致系统卡死直接关闭 VMware 虚拟机重启即可完全不会影响宿主机的 Windows 系统这大大降低了试错成本。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Vue3+ECharts5数据可视化大屏项目架构与性能优化实战 2026/9/4 3:35:21

Vue3+ECharts5数据可视化大屏项目架构与性能优化实战

简介:这是一套面向前端开发者与数据可视化工程师的 Vue3 大屏实战项目源码,聚焦企业级数据监控、指挥中心等典型大屏场景,解决 ECharts5 与 Vue3 组合开发中的动态适配、组件封装、响应式渲染等核心问题。资源共61个文件,涵盖12个…

阅读更多 →
免环境YOLO标注训练工具:技术原理、应用边界与工程实践 2026/9/4 3:35:21

免环境YOLO标注训练工具:技术原理、应用边界与工程实践

从“装不好环境”到“双击即用”,免环境YOLO标注训练工具正在把大批被 CUDA、conda、opencv 劝退的开发者重新拉回目标检测这条路上。这篇文章不吹“零门槛神兵”,而是把免环境 YOLO 标注训练工具的技术本质、适用场景和真实边界拆开讲清楚:它…

阅读更多 →
蓝牙音箱项目设计之46:整机验证中的电源、天线与声学干扰解析 2026/9/4 3:35:21

蓝牙音箱项目设计之46:整机验证中的电源、天线与声学干扰解析

蓝牙音箱项目设计做到第 46 个节点时,很多模块其实已经能单独跑了。蓝牙可搜索,音乐能播放,功放也不发烫,电池可以充电,外壳甚至打样过几轮。但恰恰是这种“看起来快完成”的时候,项目最容易卡住&#xff1…

阅读更多 →
Total Uninstall 深入解析:从安装监视到彻底清理 Windows 软件残留 2026/9/4 3:35:21

Total Uninstall 深入解析:从安装监视到彻底清理 Windows 软件残留

每个 Windows 用户几乎都遇到过这种情况:某个软件用了一段时间不想用了,在“设置”里点了卸载,安装向导也提示“卸载完成”,结果打开“开始菜单”还在,右键菜单里有关联项,电脑重新启动后又弹出来一个找不到…

阅读更多 →
Label Studio与YOLOv8免环境目标检测标注训练实战 2026/9/4 3:35:21

Label Studio与YOLOv8免环境目标检测标注训练实战

很多做 CV 方向的同学,第一次接触 YOLO 目标检测时,最头疼的往往不是模型结构,而是“数据从哪来、标注怎么做、环境怎么搭”。网上教程很多,但要么只讲标注,要么只讲训练,中间的数据转换环节经常一笔带过。…

阅读更多 →
用Notion搭建个人阅读追踪器:数据库、公式与自动化实践 2026/9/4 3:32:21

用Notion搭建个人阅读追踪器:数据库、公式与自动化实践

这次我们来看一个很多人已经在用、但大多数人只把它当作“云笔记”的工具:Notion。我要做的事不是介绍记笔记的排版技巧,而是把它当成一套轻量级数据库系统来用,搭出一个能长期维护的阅读追踪器:书单管理、阅读状态、评分、翻开与…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞