操作系统实验 C++实现生产者-消费者问题

实验目的

1、进一步加深理解进程同步的概念

2、加深对进程通信的理解

3、了解Linux下共享内存的使用方法

实验内容

1、按照下面要求,写两个c程序,分别是生产者producer.c以及customer.c

2、一组生产者和一组消费者进程共享一块环形缓冲区

使用共享内存+信号量实现生产者-消费者

1、生产者进程:在第0个缓冲区写入a,第1个写入b,……,第9个写入j,并在屏幕上打印:“Producer-pid:write Y”,其中Y为写入字符,pid为生产者进程的进程ID;

2、消费者进程:依次从缓冲区中读出写入字符,读出后,将该缓冲区置为X,并在屏幕上打印:“Customer:read Y”,其中Y为读出字符,pid为消费者进程的进程ID;

基本思路

  • 定义一个数据结构:

typedef struct{         

        int write;//当前要写的缓冲区         i

        nt read;//当前要读的缓冲区         

        char buf[10];//10个缓冲区

}shared_buf;

  • 创建一个大小为sizeof(shared_buf)的共享内存
  • Producer:在buf[write]写字符‘a’+ write,然后write = (++write)% 10;
  • Customer:读buf[read]中字符,并置buf[read] = ‘X’,然后read = (++read)% 10;
  • 使用信号量:full、empty、mutex来进行同步及互斥

参考:共享内存

Linux POSIX共享内存

Linux System V共享内存

实验代码

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>// 定义共享数据结构
typedef struct {int write;int read;char buf[10];
} shared_buf;// 信号量句柄
HANDLE empty_semaphore;
HANDLE full_semaphore;
HANDLE mutex_semaphore;// 共享内存句柄
HANDLE shared_memory_handle;
shared_buf* shared_memory_ptr;// 生产者函数
unsigned __stdcall producer(void* arg) {int pid = _getpid();for (int i = 0; i < 20; i++) {// 等待有空缓冲区WaitForSingleObject(empty_semaphore, INFINITE);// 互斥访问共享内存WaitForSingleObject(mutex_semaphore, INFINITE);char ch = 'a' + i;shared_memory_ptr->buf[shared_memory_ptr->write] = ch;printf("Producer - %d: write %c\n", pid, ch);shared_memory_ptr->write = (shared_memory_ptr->write + 1) % 10;ReleaseSemaphore(mutex_semaphore, 1, NULL);ReleaseSemaphore(full_semaphore, 1, NULL);}return 0;
}// 消费者函数
unsigned __stdcall consumer(void* arg) {int pid = _getpid();for (int i = 0; i < 20; i++) {// 等待有满缓冲区WaitForSingleObject(full_semaphore, INFINITE);// 互斥访问共享内存WaitForSingleObject(mutex_semaphore, INFINITE);char ch = shared_memory_ptr->buf[shared_memory_ptr->read];shared_memory_ptr->buf[shared_memory_ptr->read] = 'X';printf("Consumer - %d: read %c\n", pid, ch);shared_memory_ptr->read = (shared_memory_ptr->read + 1) % 10;ReleaseSemaphore(mutex_semaphore, 1, NULL);ReleaseSemaphore(empty_semaphore, 1, NULL);}return 0;
}int main() {// 创建信号量empty_semaphore = CreateSemaphore(NULL, 10, 10, NULL);full_semaphore = CreateSemaphore(NULL, 0, 10, NULL);mutex_semaphore = CreateSemaphore(NULL, 1, 1, NULL);// 创建共享内存shared_memory_handle = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,sizeof(shared_buf),"SharedMemory");if (shared_memory_handle == NULL) {perror("CreateFileMapping");return 1;}shared_memory_ptr = (shared_buf*)MapViewOfFile(shared_memory_handle,FILE_MAP_ALL_ACCESS,0,0,sizeof(shared_buf));if (shared_memory_ptr == NULL) {perror("MapViewOfFile");CloseHandle(shared_memory_handle);return 1;}// 初始化共享内存shared_memory_ptr->write = 0;shared_memory_ptr->read = 0;for (int i = 0; i < 20; i++) {shared_memory_ptr->buf[i] = 'X';}// 创建生产者和消费者线程unsigned thread_id_producer;unsigned thread_id_consumer;HANDLE producer_thread = (HANDLE)_beginthreadex(NULL, 0, producer, NULL, 0, &thread_id_producer);HANDLE consumer_thread = (HANDLE)_beginthreadex(NULL, 0, consumer, NULL, 0, &thread_id_consumer);// 等待线程结束WaitForSingleObject(producer_thread, INFINITE);WaitForSingleObject(consumer_thread, INFINITE);// 清理资源UnmapViewOfFile(shared_memory_ptr);CloseHandle(shared_memory_handle);CloseHandle(empty_semaphore);CloseHandle(full_semaphore);CloseHandle(mutex_semaphore);CloseHandle(producer_thread);CloseHandle(consumer_thread);return 0;
}

实验结果

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

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

相关文章

无人机在森林中的应用!

一、森林资源调查 无人机可以利用遥感技术快速获取所需区域高精度的空间遥感信息&#xff0c;对森林图斑进行精确区划。相较于传统手段&#xff0c;无人机调查具有低成本、高效率、高时效的特点&#xff0c;尤其在地理环境条件不好的区域&#xff0c;调查人员无法或难以到达的…

Android学生信息管理APP的设计与开发

1. 项目布局设计 页面1&#xff1a;学生信息添加页面 采用线性布局&#xff0c;页面中控件包含TextView、editView、Button等。 布局核心代码如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http…

AI(12)-飘带

1.【钢笔工具】画第一条曲线 2.【钢笔工具】画第二条曲线 3-全选两条曲线-【对象】-【混合】-【混合选项】-【指定的步数】-【15】 3-1-【对象】-【混合】-【建立】 4-双击打开【渐变工具】 4-1-【类型&#xff1a;线性】 4-2-点击切换【描边】在上方 4-3-关闭【填色】 4-4-点…

智能指针原理、使用和实现——C++11新特性(三)

目录 一、智能指针的理解 二、智能指针的类型 三、shared_ptr的原理 1.引用计数 2.循环引用问题 3.weak_ptr处理逻辑 四、shared_ptr的实现 五、定制删除器 六、源码 一、智能指针的理解 问题&#xff1a;什么是智能指针&#xff1f;为什么要有智能指针&#xff1f;智…

NIST 发布后量子密码学转型战略草案

美国国家标准与技术研究所 (NIST) 发布了其初步战略草案&#xff0c;即内部报告 (IR) 8547&#xff0c;标题为“向后量子密码标准过渡”。 该草案概述了 NIST 从当前易受量子计算攻击的加密算法迁移到抗量子替代算法的战略。该草案于 2024 年 11 月 12 日发布&#xff0c;开放…

使用uniapp开发微信小程序使用uni_modules导致主包文件过大,无法发布的解决方法

在使用uniapp开发微信小程序时候&#xff0c;过多的引入uni_modules的组件库&#xff0c;会导致主包文件过大&#xff0c;导致无法上传微信小程序&#xff0c;主包要求大小不超过1.5MB.分包大小每个不能超过2M。 解决方法&#xff1a;分包。 1.对每个除了主页面navbar的页面进…

WPF窗体基本知识-笔记-命名空间

窗体程序关闭方式 命名空间:可以理解命名空间的作用为引用下面的控件对象 给控件命名:一般都用x:Name,也可以用Name但是有的控件不支持 布局控件(容器)的类型 布局控件继承于Panel的控件,其中下面的border不是布局控件,panel是抽象类 在重叠的情况下,Zindex值越大的就在上面 Z…

【android USB 串口通信助手】stm32 源码demo 单片机与手机通信 Android studio 20241118

android 【OTG线】 接 下位机STM32【USB】 通过百度网盘分享的文件&#xff1a;USBToSerialPort.apk 链接&#xff1a;https://pan.baidu.com/s/122McdmBDUxEtYiEKFunFUg?pwd8888 提取码&#xff1a;8888 android 【OTG线】 接 【USB转TTL】 接 【串口(下位机 SMT32等)】 需…

SpringBoot源码解析(四):解析应用参数args

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args 目录…

使用IDEA+Maven实现MapReduced的WordCount

使用IDEAMaven实现MapReduce 准备工作 在桌面创建文件wordfile1.txt I love Spark I love Hadoop在桌面创建文件wordfile2.txt Hadoop is good Spark is fast上传文件到Hadoop # 启动Hadoop cd /usr/local/hadoop ./sbin/start-dfs.sh # 删除HDFS的hadoop对应的input和out…

Spring Cloud Ribbon 实现“负载均衡”的详细配置说明

1. Ribbon 介绍 Ribbon 是什么 &#xff1f; 1.Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端&#xff0c;负载均衡的工具 2.Ribbon 主要功能是提供客户端负载均衡算法和服务调用 3.Ribbon 客户端组件提供一系列完善的配置项如“连接超时&#xff0c;重试” 4…

TSMC12nm工艺数字IC后端实现难点都有哪些?

大家知道咱们社区近期TSMC 12nm ARM Cortexa-A72(1P9M 6Track Metal Stack)即将开班。这里小编要强调一点:不要认为跑了先进工艺的项目就会很有竞争力&#xff01;如果你仅仅是跑个先进工艺的flow&#xff0c;不懂先进工艺在数字IC后端实现上的不同点&#xff0c;为何有这样的不…

使用微信小程序调用飞桨PaddleX平台自行训练的模型——微信小程序用训练的牡丹花模型Demo测试

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

【C++】基础篇二、引用详解

文章目录 1.引用的概念和定义2.引用的特性3.引用的使用3.1 做函数返回值3.2 传参 3.3 其他使用 4.const的运用引用的权限问题&#xff1b;const修饰引用&#xff1b; 5.指针和引用的对比 1.引用的概念和定义 在介绍概念之前先说一下引用的符号——“ & ”&#xff1b;对于这…

D3基础:绘制圆形、椭圆形、多边形、线、路径、矩形

在D3.js中&#xff0c;可以通过SVG元素来创建各种几何图形。以下是D3.js中常用的几何图形及其简单的创建方法&#xff1a; 1. 圆形 (Circle) 圆形是最基本的形状之一&#xff0c;可以通过<circle>标签来创建。 <!DOCTYPE html> <html> <head><met…

前端监控之sourcemap精准定位和还原错误源码

一、概述 在前端开发中&#xff0c;监控和错误追踪是确保应用稳定性和用户体验的重要环节。 随着前端应用的复杂性增加&#xff0c;JavaScript错误监控变得尤为重要。在生产环境中&#xff0c;为了优化加载速度和性能&#xff0c;前端代码通常会被压缩和混淆。这虽然提升了性…

MySQL的表的约束以及查询

本篇文章继续给大家梳理MySQL的操作 目录 表的约束 空属性 默认值 列描述 0填充 主键 主键常识 添加主键 删除主键 复合主键 自增长 唯一键 外键 单/多行输入与全/指定列的插入 全列输入 单行输入 多行插入 指定列插入 单行输入 多行插入 插入否则更新 替换…

MySQL 日志 主从复制

1. 日志 学习链接&#xff0c;click mysql中有4种日志&#xff1a; 错误日志二进制日志查询日志慢查询日志 1.1 错误日志 错误日志是MySQL中最重要的日志之一&#xff0c;它记录了当mysqld启动和停止时&#xff0c;以及服务器在运行过程中发生任何严重错误时的相关信息。当…

自动驾驶系列—深入解析自动驾驶车联网技术及其应用场景

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

基于YOLOv8深度学习的公共卫生防护口罩佩戴检测系统(PyQt5界面+数据集+训练代码)

在全球公共卫生事件频发的背景下&#xff0c;防护口罩佩戴检测成为保障公众健康和控制病毒传播的重要手段之一。特别是在人员密集的公共场所&#xff0c;例如医院、学校、公共交通工具等地&#xff0c;口罩的正确佩戴对降低病毒传播风险、保护易感人群、遏制疫情扩散有着至关重…