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

news2025/1/13 3:32:03

说明

本文是《操作系统概念(第九版)》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.coloradmin.cn/o/780878.html

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

相关文章

SJA1000的简单调试

文章目录 基本过程SJA1000波特率计算公式验收滤波器使用其他关于CLKOUT测试寄存器初始化过程中会产生中断扩展帧、标准帧的区分计算器 基本过程 SJA1000的接口连接到FPGA上&#xff0c;采用软核进行CAN数据的收发。调试花了1天多的时间&#xff0c;有点波折&#xff0c;下面按…

最新版edge浏览器中安装xpath插件

最近在跟着尚硅谷进行爬虫的学习&#xff0c;老师给出了在谷歌浏览器安装Xpath插件的方法&#xff0c;由于电脑上面未安装谷歌浏览器&#xff0c;所以在网上搜索了在edge上安装Xpath插件的方法&#xff0c;安装完成以后发现使用快捷键 CTRL SHIFTX不能够打开&#xff0c;以为是…

[java安全]CommonsCollections2

文章目录 【java安全】CommonsCollections2前言Commons-Collections4版本中能否调用cc6等链子&#xff1f;PriorityQueue利用链PriorityQueueTransformingComparator**使用了phithon的总结&#xff1a;**POC 进阶POCPOC分析调用链 【java安全】CommonsCollections2 前言 Apac…

【Flutter问题记录】Android Studio不显示(右上角main.dart左边)设备栏

记录一下今天遇到的情况&#xff1a; 用android studio打开项目&#xff0c;我检查了&#xff0c;已经配置了flutter sdk和android sdk&#xff0c;但是右上角main.dart左边的设备栏就是不显示。 解决方法&#xff1a; 恢复如初&#xff1a;

【密码学】三、分组密码概述

分组密码 1.分组密码简介2.分组密码的基本原理2.1代换2.2扩散2.3混淆 3.分组密码的结构3.1Feistel网络3.1.1平衡Feistel网络3.1.2不平衡Feistel网络 3.2SP网络 4.分组密码的设计 分组密码算法是将输入数据划分成固定长度的组进行加密和解密的一类对称密码算法。本章主要介绍分组…

零基础深度学习——学习笔记1 (逻辑回归)

前言 因为各种各样的原因要开始学习深度学习了&#xff0c;跟着吴恩达老师的深度学习视频&#xff0c;自己总结一些知识点&#xff0c;以及学习中遇到的一些问题&#xff0c;以便记录学习轨迹以及以后复习使用&#xff0c;为了便于自己理解&#xff0c;我会将一些知识点用以个…

MySQL 中NULL和空值的区别

MySQL 中NULL和空值的区别&#xff1f; 简介NULL也就是在字段中存储NULL值&#xff0c;空值也就是字段中存储空字符(’’)。区别 1、空值不占空间&#xff0c;NULL值占空间。当字段不为NULL时&#xff0c;也可以插入空值。 2、当使用 IS NOT NULL 或者 IS NULL 时&#xff0…

了解 3DS MAX 3D摄像机跟踪设置:第 4 部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 项目设置 步骤 1 打开“后效”。 打开后效果 步骤 2 转到合成>新合成以创建新合成。 将“宽度”和“高度”值分别设置为 1280 和 720。将帧速率设置为 25&#xff0c;将持续时间设置为 12 秒。单…

Jenkins发送的邮箱中没有带配置的压缩附件

【问题描述】&#xff1a;Jenkins中明明配置了邮箱发送时要带压缩附件&#xff0c;收到的邮箱中却没有附件内容 【问题定位】&#xff1a;压缩附件没有放在Jenkins工作空间下&#xff0c;所以发送的邮件并未发送附件 【解决办法】&#xff1a; 1&#xff09;把压缩附件放到J…

Scoop安装配置MySQL最详细版(含Navicat连接MySQL)

这是在DataWhale的第一次打卡文章&#xff0c;也是时隔三年再动笔&#xff0c;希望持续下去。 我没想到花费了一整天的时间来配置我的写作环境&#xff08;TyporaPicGo腾讯云oss&#xff09;&#xff0c;因为我不想我的文字局限在某个平台上&#xff0c;很被动&#xff0c;想要…

如何在小程序首页隐藏商品分类

​因为在分类页面有显示分类&#xff0c;所以有的商家希望在首页就不显示分类啦。下面就介绍一下如何在首页隐藏商品分类。 在小程序管理员后台->页面设置->首页&#xff0c;显示商品分类设置为否。设置后&#xff0c;在小程序首页商品分类就不会显示啦。注意&#xff1a…

手机word文档怎么转换成pdf?分享两种方法

手机word文档怎么转换成pdf&#xff1f;在如今信息化的时代&#xff0c;电子文档已经成为人们日常办公不可或缺的一部分。随着科技的不断进步&#xff0c;电子文档的格式也在不断发展。PDF作为电子文档的一种重要格式&#xff0c;被广泛使用。那么&#xff0c;如何将手机上的Wo…

zabbix通过JMX监控tomcat

目录 1&#xff09;配置java网关 2&#xff09;修改tomcat 3&#xff09;修改tomcat启动脚本 4&#xff09;启动tomcat 5&#xff09;Zabbix-web端配置——添加JMX信息 6&#xff09;导入模板​编辑 7&#xff09; 为server.zabbix.com添加模板 8&#xff09;图形如下 9&…

SAP从放弃到入门系列之-5种库存转储测试

​前段时间发了小蜘蛛同学写的《STO 库存转储总结》这篇文章&#xff0c;一直没发测试的示例&#xff0c;4年前写的文章了&#xff0c;今天才从草稿箱翻出来。 文章目录导航 一、Plant to plant 1 step二、Plant to plant 2 steps中转库存&#xff08;Stock In Transfer&#…

图数据库Neo4j学习二——cypher基本语法

1命名规范 名称应以字母字符开头&#xff0c;不以数字开头&#xff0c;名称不应包含符号&#xff0c;下划线除外可以很长&#xff0c;最多65535( 2^16 - 1) 或65534字符&#xff0c;具体取决于 Neo4j 的版本名称区分大小写。:PERSON和:Person是:person三个不同的标签&#xff…

Unity进阶-ui框架学习笔记

文章目录 Unity进阶-ui框架学习笔记 Unity进阶-ui框架学习笔记 笔记来源课程&#xff1a;https://study.163.com/course/courseMain.htm?courseId1212756805&_trace_c_p_k2_8c8d7393c43b400d89ae94ab037586fc 最上面的管理层&#xff08;canvas&#xff09; using System…

数仓学习---12、数仓开发之ADS层

星光下的赶路人star的个人主页 知世故而不世故 是善良的成熟 文章目录 1、数仓开发之ADS层1.1 流量主题1.1.1 各渠道流量统计1.1.2 路径分析 1.2 用户主题1.2.1 用户变动统计1.2.2 用户留存率1.2.3 用户新增活跃统计1.2.4 用户行为漏斗分析1.2.5 新增交易用户统计 1.3 商品主题…

Sentinel 规则持久化到 Nacos

一、Sentinel规则管理模式&#x1f349; Sentinel的控制台规则管理有三种模式&#xff1a; 原始模式&#x1f95d; 原始模式&#xff1a;控制台配置的规则直接推送到Sentinel客户端&#xff0c;也就是我们的应用。然后保存在内存中&#xff0c;服务重启则丢失 pull模式&#…

【重点:单例模式】特殊类设计

请设计一个类&#xff0c;只能在堆上创建对象 方式如下&#xff1a; 将构造函数设置为私有&#xff0c;防止外部直接调用构造函数在栈上创建对象。向外部提供一个获取对象的static接口&#xff0c;该接口在堆上创建一个对象并返回。将拷贝构造函数设置为私有&#xff0c;并且…

了解 3DS MAX 3D摄像机跟踪设置:第 2 部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 项目设置 步骤 1 打开“后效”。 打开后效果 步骤 2 转到合成>新合成以创建新合成。 将“宽度”和“高度”值分别设置为 1280 和 720。将帧速率设置为 25&#xff0c;将持续时间设置为 12 秒。单…