Linux-代码实现通过system v共享内存实现的进程间的通信

一.makefile编写

.PHONY:all
all:processa processbprocessa : processa.ccg++ -o $@ $^ -g -std=c++11
processb : processb.ccg++ -o $@ $^ -g -std=c++11.PHONY:clean
clean:rm -rf processa processb

二.创建system v共享内存

        1.系统调用接口          

                key:a.key是一个数值,在内核中具有唯一性,可以让不同的进程标识唯一的共享内存。

                        b.第一个进程可以通过key创建共享内存,从此第二个进程在拿着相同的key就可以和第一个进程看到同一块共享内存了。

                        c.这个key保存在共享内存的描述结构体中。

                        d.需要强调的是key是由用户给出相应的信息然后,系统根据算法来返回一个计算到的key。

                        ftok函数调用成功返回key值,失败返回-1。

                        用户在程序中调用这个函数就可以得到一个key。然后将这个key传给shmget就可以得到一个又这个key在内核中唯一标识的共享内存。

                size:所需要的共享内存的大小

            shmflg:IPC_CREAT(可以单独使用)其作用是如果这个key在内核中没有就创建一个新的共享内存,如果有就直接获取它。

                           IPC_EXCL(不可以单独使用要配合IPC_CREAT一起使用)作用是如果申请的共享空间存在了就会出错返回,不存在就创建,确保我们每次的调用创建的都是新的共享内存。

                返回值:成功返回共享内存的标识符shmid,识别返回-1。 

                shmid和key的对比:

                                shmid是在进程内用来表示共享内存唯一性的。

                                 key是在内核中表示共享内存唯一性的。一般这个key只在创建共享内存的时候使用,其他的时候就不用了。

        

        2.代码实现
#include <string>
#include <cerrno>
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>#include "log.hpp"using namespace std;//使用日志
Log log;const string pathname = "/home/cky";
const int proj_id     = 0x6666;key_t GetKey()
{key_t key = ftok(pathname.c_str(), proj_id);if(key < 0){log(Fatal, "ftok error : %s", strerror(errno));exit(1);}log(Info, "ftok success, key is %d", key);return key;}#define SIZE 4096
int GetshareMemHelper(int flag)
{key_t key = GetKey();int shmid = shmget(key, SIZE, flag);if(shmid < 0){log(Fatal, " create share memory error : %s", strerror(errno));exit(1);}log(Info, " create share memory success, shmid is : %d", shmid);return shmid;
}int Greateshm()
{return GetshareMemHelper(IPC_CREAT | IPC_EXCL);
}int Getshm()
{return GetshareMemHelper(IPC_CREAT);
}

                查看我们创建的共享内存:

                创建的共享内存如果我们不手动释放掉的话,即使是使用的进程退出了,系统也不会主动的释放掉它。 

                perm:是共享内存的使用权限,此时我们的程序中并没有指定权限所以是0。 

int Greateshm()
{return GetshareMemHelper(IPC_CREAT | IPC_EXCL | 0666);
}int Getshm()
{return GetshareMemHelper(IPC_CREAT);
}

 

                nattch:是同这个共享内存关联的进程数,此时我们并没有为这个新创建的共享内存关联进程,所以是0。 

                在bash上删除我们创建的共享内存:

        

三.将创建好的共享内存同进程关联在一起 ,去除关联,释放共享内存资源

        1.系统调用接口                

                shmaddr:将指定的共享内存关联到进程地址空间中的什么位置,如果是NULL是由操作系统决定,此时具体在什么位置通过返回值来确定。

                shmflg:默认是0;

         

                        去关联函数。

                        cmd:IPC_RMID 是设置为删除。

                        buf:是类似于内核中管理共享内存的结构体,删除时设置为NULL就可以。

        2.代码实现
    //同共享内存关联char* shmaddr = nullptr;shmaddr = (char*)shmat(shmid, NULL, 0);//去除关联shmdt(shmaddr);//释放共享内存资源shmctl(shmid, IPC_RMID, NULL);

          一但创建好的共享内存和进程所关联了,那么就可以直接使用了,不需要系统调用。

四.进行通信

        processa.cc

#include "comm.hpp"int main(void)
{//创建共享内存int shmid = 0;shmid = Greateshm();//同共享内存关联char* shmaddr = nullptr;shmaddr = (char*)shmat(shmid, NULL, 0);//进行通信while(true){cout << "client say@ " << shmaddr << endl; //直接访问共享内存}//去除关联shmdt(shmaddr);//释放共享内存资源shmctl(shmid, IPC_RMID, NULL);return 0;
}

        processb.cc

#include "comm.hpp"int main()
{int shmid = Getshm();char *shmaddr = (char*)shmat(shmid, nullptr, 0);// 一旦有了共享内存,挂接到自己的地址空间中,你直接把他当成你的内存空间来用即可!// 不需要调用系统调用// ipc codewhile(true){cout << "Please Enter@ ";fgets(shmaddr, 4096, stdin);}shmdt(shmaddr);return 0;
}

        单纯的共享内存是没有同步互斥的,但是可以通过加管道的方式来实现。

五.通过管道实现共享内存的同步互斥

        命名管道:

enum
{FIFO_CREATE_ERR = 1,FIFO_DELETE_ERR,FIFO_OPEN_ERR
};#define MODE 0664
#define FIFO_FILE "./myfifo"class Init
{
public:Init(){// 创建管道int n = mkfifo(FIFO_FILE, MODE);if (n == -1){perror("mkfifo");exit(FIFO_CREATE_ERR);}}~Init(){int m = unlink(FIFO_FILE);if (m == -1){perror("unlink");exit(FIFO_DELETE_ERR);}}
};

        processa.cc

#include "comm.hpp"int main(void)
{//创建共享内存int shmid = 0;shmid = Greateshm();//同共享内存关联char* shmaddr = nullptr;shmaddr = (char*)shmat(shmid, NULL, 0);//创建管道Init init;//打开管道int fd = open(FIFO_FILE, O_RDONLY);if(fd < 0){log(Fatal, "error string: %s, error code: %d", strerror(errno), errno);exit(FIFO_OPEN_ERR);}//进行通信while(true){char c;ssize_t s = read(fd, &c, 1);if(s == 0) break;else if(s < 0) break;cout << "client say@ " << shmaddr << endl; //直接访问共享内存}//去除关联shmdt(shmaddr);//释放共享内存资源shmctl(shmid, IPC_RMID, NULL);return 0;
}

        processb.cc

#include "comm.hpp"int main()
{int shmid = Getshm();char *shmaddr = (char*)shmat(shmid, nullptr, 0);int fd = open(FIFO_FILE, O_WRONLY);if(fd < 0){log(Fatal, "error string: %s, error code: %d", strerror(errno), errno);exit(FIFO_OPEN_ERR);}// 一旦有了共享内存,挂接到自己的地址空间中,你直接把他当成你的内存空间来用即可!// 不需要调用系统调用// ipc codewhile(true){cout << "Please Enter@ ";fgets(shmaddr, 4096, stdin);write(fd, "c", 1); // 通知对方}shmdt(shmaddr);return 0;
}

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

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

相关文章

【Java系列】函数式接口编程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

数据结构之栈

作者简介&#xff1a; zoro-1&#xff0c;目前大二&#xff0c;正在学习Java&#xff0c;数据结构等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; 数据结构之栈 概念特性常用方法栈模拟实现接口实现…

OSHI-操作系统和硬件信息库

文章目录 引言一、快速入门1.1 OSHI的简介1.2 引入依赖1.3 涉及的包&#xff08;package&#xff09;1.4 涉及的核心类 二、操作系统信息&#xff1a;OperatingSystem2.1 总揽2.2 文件系统信息&#xff1a;FileSystem2.3 网络参数信息&#xff1a;NetworkParams2.4 进程信息&am…

C++ 函数详解

目录 函数概述 函数的分类 函数的参数 函数的调用 函数的嵌套调用 函数的链式访问 函数声明和定义 函数递归 函数概述 函数——具有某种功能的代码块。 一个程序中我们经常会用到某种功能&#xff0c;如两数相加&#xff0c;如果每次都在需要用到时实现&#xff0c;那…

状态机的练习:按键控制led灯

设计思路&#xff1a; 三个按键控制led输出。 三个按键经过滤波(消抖)&#xff0c;产生三个按键标志信号。 三个led数据的产生模块&#xff08;流水&#xff0c;跑马&#xff0c;闪烁模块&#xff09;&#xff0c;分别产生led信号。 这六路信号&#xff08;三路按键信号&am…

LAMP部署

一.什么是LAMP&#xff1f; LAMP架构是企业网站应用模式之一&#xff0c;包括linux系统&#xff0c;apache网站服务&#xff0c;mysql数据库服务器&#xff0c;php&#xff08;python&#xff09;网页编程语言。 linux&#xff08;平台&#xff09;&#xff1a;作为LAMP架构的…

西南科技大学模拟电子技术实验六(BJT电压串联负反馈放大电路)预习报告

一、计算/设计过程 BJT电压串联负反馈放大电路图1-1-1-1为BJT电压串联负反馈放大实验电路,若需稳定输出电压,减小从信号源所取电流,可引入电压串联负反馈闭合开关。 图1-1-1-1 理论算法公式(1)闭环电压放大倍数 (2)反馈系数 (3)输入电阻 (4)输出电阻 计算过程。开环…

Redis常见类型

常用类型String字符串类型Hash字典类型List列表类型Set集合类型ZSet有序集合类型 Java程序操作Redis类型代码操作Redis 常用类型 String字符串类型 使用方式&#xff1a; 使用场景&#xff1a; Hash字典类型 字典类型(Hash) 又被成为散列类型或者是哈希表类型&#xff0…

数据库原理: 笛卡儿积

笛卡儿积&#xff08;Cartesian Product&#xff09;是集合论中的一个概念&#xff0c;也在数据库中的查询操作中经常使用。笛卡儿积是指两个集合&#xff08;或更多集合&#xff09;之间所有可能的组合。如果有两个集合A和B&#xff0c;它们的笛卡儿积记作A B&#xff0c;表示…

蓝桥杯-平方和(599)

【题目】平方和 【通过测试】代码 import java.util.Scanner; import java.util.ArrayList; import java.util.List; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);//在此…

06、基于内容的过滤算法Tensorflow实现

06、基于内容的过滤算法Tensorflow实现 开始学习机器学习啦&#xff0c;已经把吴恩达的课全部刷完了&#xff0c;现在开始熟悉一下复现代码。全部工程可从最上方链接下载。 05、基于梯度下降的协同过滤算法中已经介绍了协同过滤算法的基本实现方法&#xff0c;但是这种方法仅…

Redis5新特性-stream

Stream队列 Redis5.0 最大的新特性就是多出了一个数据结构 Stream&#xff0c;它是一个新的强大的 支持多播的可持久化的消息队列&#xff0c;作者声明 Redis Stream 地借鉴了 Kafka 的设计。 生产者 xadd 追加消息 xdel 删除消息&#xff0c;这里的删除仅仅是设置了标志位&am…

【每日一题】重新规划路线

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;深度优先搜索方法二&#xff1a;广度优先搜索 写在最后 Tag 【深搜】【广搜】【树】【2023-12-07】 题目来源 1466. 重新规划路线 题目解读 题目给定一张由 n个点&#xff08;使用 0 到 n−1 编号&#xff09;&#…

在Spring Cloud使用Hystrix核心组件,并注册到Eureka注册中心去

其实吧&#xff0c;写Spring Cloud系列&#xff0c;我有时候觉得也挺难受的&#xff0c;因为Spring Cloud的微服务启动都需要一个一个来&#xff0c;并且在IDea中也需要占用比较大的内存&#xff0c;并且我本来可以一篇写完5大核心组件的&#xff0c;但是我却分了三篇&#xff…

探索 Linux Namespace:Docker 隔离的神奇背后

来自&#xff1a;探索云原生 https://www.lixueduan.com 原文&#xff1a;https://www.lixueduan.com/posts/docker/03-container-core/ 在 深入理解 Docker 核心原理&#xff1a;Namespace、Cgroups 和 Rootfs 一文中我们分析了 Docker 是由三大核心技术实现的。 今天就一起分…

万界星空科技MES---制造企业的加工生产模式

在现代制造业中&#xff0c;加工生产模式是制造企业组织和管理生产过程的重要方面。不同的加工模式适用于不同的生产需求和产品类型。其中流水型、离散型和混合型是三种常见的加工生产模式。1. 流水型加工模式 流水型加工模式是一种高度自动化的生产方式&#xff0c;适用于…

JavaScript实现手写签名,可触屏手写,支持移动端与PC端双端保存

目录 1.HTML模板 2.获取DOM元素和定义变量 3.创建两个canvas元素&#xff0c;并设置它们的宽度和高度 4.绑定触摸事件&#xff1a;touchstart, touchmove, touchend和click 5.实现触摸事件回调函数&#xff1a;startDrawing, draw和stopDrawing 6.实现绘制线段的函数&…

【PyTorch】模型选择、欠拟合和过拟合

文章目录 1. 理论介绍2. 实例解析2.1. 实例描述2.2. 代码实现2.2.1. 完整代码2.2.2. 输出结果 1. 理论介绍 将模型在训练数据上拟合的比在潜在分布中更接近的现象称为过拟合&#xff0c; 用于对抗过拟合的技术称为正则化。训练误差和验证误差都很严重&#xff0c; 但它们之间差…

Java程序员,你掌握了多线程吗?(文末送书)

目录 01、多线程对于Java的意义02、为什么Java工程师必须掌握多线程03、Java多线程使用方式04、如何学好Java多线程送书规则 摘要&#xff1a;互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀活动&#xff0c;社交平台的实时消息推送&#xff0c;还是在线视频平台的流…

@德人合科技 | 数据透明加密防泄密系统\文件文档加密\设计图纸加密|源代码加密防泄密软件系统,——防止内部办公终端核心文件数据/资料外泄!

一款专业的数据防泄密管理系统&#xff0c;它采用了多种加密模式&#xff0c;包括透明加密、半透明加密和落地加密等&#xff0c;可以有效地保护企业的核心数据安全。 PC端访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee …