操作系统练习:进程间通信(共享内存方式)

说明

本文是《操作系统概念(第九版)》3.4节“进程间通信”的练习。

进程间通信主要由两种模型:

  • 共享内存
  • 消息传递

本文使用共享内存的方式实现进程间的通信

file

创建消息生产者

创建生产者的主要操作包括:

  • 定义共享内存的大小、名称,以及通信消息的具体message内容
  • 定义共享内存的对象和内存映射文件指针
  • 用shm_open()方法,实例化共享内存对象(其参数包括共享内存名称和对象权限等)
  • 用ftruncate()方法,配置共享内存对象的大小
  • 用mmap()方法,创建内存映射文件,以便包含共享内存对象,它返回一个指向内存映射文件的指针,可用其访问共享内存对象
  • 最后,对共享内存的写入,是通过调用sprintf()方法和向内存映射文件指针写入格式化字符串实现(每次写入之后,都要用所写字节的数量递增指针)

创建生产者的详细代码如下,可以新建一个producer.c文件,然后将代码拷贝进去:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>int main() {/* the size of shared memory object */const int SIZE = 4096;/* name of the shared memory object */const char *name = "OS";/* strings written to the shared memory */const char *message_0 = "Hello";const char *message_1 = "World!";/* shared memory file descriptor */int shm_fd;/* pointer to shared memory object */void *ptr;/* create the shared memory object */shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);/* configure the size of the shared memory object */ftruncate(shm_fd, SIZE);/* memory map the shared memory object */ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);/* write to the shared memory object */sprintf(ptr, "%s", message_0);ptr += strlen(message_0);sprintf(ptr, "%s", message_1);ptr += strlen(message_1);printf("Written done!");return 0;
}

创建消息消费者

创建消费者的代码和创建消费者的代码有一些类似的地方,但是也有一些区别:

  • 不需要创建一个共享内存对象,而是通过名称去打开一个共享内存对象
  • 访问内存对象之后,调用了shm_unlink()方法移除了共享内存段

创建消费者的详细代码如下,可以新建一个consumer.c文件,然后将下列代码拷贝进去:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>int main(){/* the size of shared memory object */const int SIZE = 4096;/* name of the shared memory object */const char *name = "OS";/* shared memory file descriptor */int shm_fd;/* pointer to shared memory object */void *ptr;/* open the shared memory object */shm_fd = shm_open(name, O_RDONLY, 0666);/* memory map the shared memory object */ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);/* read from the shared memory object */printf("%s", (char *)ptr);/* remove the shared memroy object */shm_unlink(name);printf("\n");printf("Read done!\n");return 0;
}

编译和运行

接下来是编译两个c文件,然后执行生产者代码,最后执行消费者代码

# 编译生产者代码
gcc -o producer producer.c -lrt## 编译消费者代码
gcc -o consumer consumer.c -lrt ## 执行生产者代码
./producer## 执行消费者代码
./consumer

最终的执行效果如下:
file

报错处理

致命错误:stlib.h:没有那个文件或目录

如果有下面的报错,那么是因为引用的文件名称错误,正确的应该是 #include <stdlib.h> (我看到的书上少了一个‘d’)

producer.c:6:10: 致命错误:sys/stath:没有那个文件或目录#include <sys/stath>^~~~~~~~~~~
编译中断。

错误:‘O_RDRW’ undeclared (first use in this function); did you mean ‘O_RDWR’?

如果是下面的报错,则应该将O_RDRW改成O_RDWR

producer.c:27:36: 错误:‘O_RDRW’ undeclared (first use in this function); did you mean ‘O_RDWR’?shm_fd = shm_open(name, O_CREAT | O_RDRW, 0666);^~~~~~O_RDWR
producer.c:27:36: 附注:每个未声明的标识符在其出现的函数内只报告一次

file

‘PROT_WRITE’ undeclared, ‘MAP_SHARED’未声明

以下报错,需要新增两个文件引用:

  • #include <sys/mman.h>
  • #include <unistd.h>
producer.c:33:22: 错误:‘PROT_WRITE’ undeclared (first use in this function); did you mean ‘S_IWRITE’?ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);^~~~~~~~~~S_IWRITE
producer.c:33:34: 错误:‘MAP_SHARED’未声明(在此函数内第一次使用)ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);^~~~~~~~~~

file

对‘shm_open’未定义的引用

解决办法: 在编译命令最后加 -lrt

/tmp/ccnkitBK.o:在函数‘main’中:
producer.c:(.text+0x39):对‘shm_open’未定义的引用
collect2: 错误:ld 返回 1

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

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

相关文章

netty知识集锦2

粘包半包 粘包半包解决方案&#xff0c; 1短链接&#xff0c;它的消息边界是从链接建立到链接断开 2.定长解码器&#xff1a;服务器端选最大长度的消息作为定长&#xff0c;客户端不足补齐&#xff0c;缺点造成浪费 netty协议设计与解析 Message编码解码

AWS IAM介绍

前言 AWS是世界上最大的云服务提供商&#xff0c;它提供了很多组件供消费者使用&#xff0c;其中进行访问控制的组件叫做IAM(Identity and Access Management)&#xff0c; 用来进行身份验证和对AWS资源的访问控制。 功能 IAM的功能总结来看&#xff0c;主要分两种&#xff1…

《零基础入门学习Python》第060讲:论一只爬虫的自我修养8:正则表达式4

有了前面几节课的准备&#xff0c;我们这一次终于可以真刀真枪的干一场大的了&#xff0c;但是呢&#xff0c;在进行实战之前&#xff0c;我们还要讲讲正则表达式的实用方法和扩展语法&#xff0c;然后再来实战&#xff0c;大家多把持一会啊。 我们先来翻一下文档&#xff1a;…

openGauss学习笔记-17 openGauss 简单数据管理-表达式

文章目录 openGauss学习笔记-17 openGauss 简单数据管理-表达式17.1 简单表达式17.2 条件表达式17.3 子查询表达式17.4 数组表达式17.5 行表达式 openGauss学习笔记-17 openGauss 简单数据管理-表达式 表达式类似一个公式&#xff0c;我们可以将其应用在查询语句中&#xff0c…

25 MFC 数据库

文章目录 导入ADO库 导入ADO库 #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","rsEOF")void CADODlg::OnBnClickedBtnQuery() {//导入ADO库::CoInitialize(NULL);//初始化COM库_ConnectionPtr pCo…

《面试1v1》如何提高远程用户的吞吐量

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Flutter动画库:animations(路由过渡动画或者页面切换动画)

animations animations 是一个 Flutter 库&#xff0c;它提供了一组用于创建动画效果的工具和组件。这个库的核心重点是路由过渡动画或者页面切换动画 地址 https://pub-web.flutter-io.cn/packages/animations 安装 flutter pub add animations看了下官方文档和官方例子&a…

计科web常见错误排错【HTTP状态404、导航栏无法点开、字符乱码及前后端数据传输呈现、jsp填写的数据传到数据库显示null、HTTP状态500】

web排错记录 在使用javaweb的过程中会出现的一些错误请在下方目录查找。 目录 错误1&#xff1a;HTTP状态404——未找到 错误2&#xff1a;导航栏下拉菜单无法点开的问题 错误3&#xff1a;字符乱码问题 错误4&#xff1a;jsp网页全部都是&#xff1f;&#xff1f;&#x…

【单片机】MSP430F149单片机,晨启,音乐播放器,蜂鸣器音乐

四、音乐播放器 任务要求&#xff1a; 设计制作一个简易音乐播放器&#xff08;通过手柄板上的蜂鸣器发声&#xff0c;播放2到4首音 乐&#xff09;&#xff0c;同时LED模块闪烁&#xff0c;给人视、听觉美的感受。 评分细则&#xff1a; 按下播放按键P15开始播放音乐&#x…

【C++】继承基础知识及简单应用,使用reportSingleClassLayout(在Visual Studio开发人员命令提示窗口)查看派生类详细信息

author&#xff1a;&Carlton tag&#xff1a;C topic&#xff1a;【C】继承基础知识及简单应用&#xff0c;使用reportSingleClassLayout&#xff08;在Visual Studio开发人员命令提示窗口&#xff09;查看派生类详细信息 website&#xff1a;黑马程序员C date&#xf…

微信小程序原生上传图片和预览+云函数上传

1.前台页面 1.1wxml问阿金 <!-- 说明一个上传页面的按钮 --> <button type"primary" bindtap"uploadPage">上传页面展示</button> <!-- 声明一个上传服务器的按钮 --> <button type"warn" bindtap"uploadSeve…

第四讲:MySQL中DDL一些基本数据类型及表的创建、查询

目录 1、创建表:2、DDL一些基本数据类型&#xff1a; 1、创建表: 部分单词及解析&#xff1a; 1、tables:表 2、comment:评论&#xff0c;解释 3、gender:性别 4、neighbor&#xff1a;邻居 1、创建表&#xff1a;&#xff08;注&#xff1a;在自定义数据库操作&#xff0c;…

spring中bean实例化的三种方式 -- Spring入门(二)

文章目录 前言1.Bean实例化简介2.bean的实例化 -- 构造方法3.bean的实例化 -- 静态工厂实例化4.bean实例化 -- 实例工厂和FactoryBean5.三种bean实例化方式的区别 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客&#xff0c;方便日后回顾。…

Leetcode 112. 路径总和

题目链接&#xff1a;https://leetcode.cn/problems/path-sum/description/ 思路 递归&#xff0c;先序遍历二叉树&#xff0c;每遍历一个节点便减去当前存储值&#xff08;targetSum targetSum - root.val&#xff09;&#xff1b;当到达某个节点等于targetSum (targetSum…

labview 子画面插入面板

1.前言 在前面一篇文章中描述了弹框式显示子画面&#xff0c; labview 弹窗(子vi)_weixin_39926429的博客-CSDN博客 本文介绍插入式显示子画面。 本文的主题在以前的文章中介绍过&#xff0c; labview 插入子面板_labview插入子面板_weixin_39926429的博客-CSDN博客 借用…

机器学习算法分类

机器学习根据任务的不同&#xff0c;可以分为监督学习、无监督学习、半监督学习、强化学习。 1. 无监督学习 训练数据不包含任何类别信息。无监督学习里典型例子是聚类。要解决的问题是聚类问题和降维问题&#xff0c;聚类算法利用样本的特征&#xff0c;将具有相似特征的样本…

微服务 云原生:搭建 K8S 集群

为节约时间和成本&#xff0c;仅供学习使用&#xff0c;直接在两台虚拟机上模拟 K8S 集群搭建 踩坑之旅 系统环境&#xff1a;CentOS-7-x86_64-Minimal-2009 镜像&#xff0c;为方便起见&#xff0c;直接在 root 账户下操作&#xff0c;现实情况最好不要这样做。 基础准备 关…

React18和React16合成事件原理(附图)

&#x1f4a1; React18合成事件的处理原理 “绝对不是”给当前元素基于addEventListener做的事件绑定&#xff0c;React中的合成事件&#xff0c;都是基于“事件委托”处理的&#xff01; 在React17及以后版本&#xff0c;都是委托给#root这个容器&#xff08;捕获和冒泡都做了…

【java】java中注解的简介,如何自定义注解,有哪些类型,有什么作用

java注解 注解的定义 Java 注解用于为 Java 代码提供元数据。作为元数据&#xff0c;注解不直接影响你的代码执行&#xff0c;但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。 首先要明确一点的是&#xff0c;注解并没有实际的作用&…

八股文(消息队列)

文章目录 1. RabbitMQ特点2. 如何保证消息的可靠性3. RabbitMQ消息的顺序性4. 实现RabbitMQ的高可用性5. 如何解决消息队列的延时以及过期失效问题&#xff1f;6. RabbitMQ死信队列7. RabbitMQ延迟队列8.RabbitMQ的工作模式9. RabbitMQ消息如何传输10. 核心概念10.1 生产者和消…