Linux进程通信——共享内存

概念

共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区。

特点

共享内存是最快的一种 IPC,因为进程是直接对内存进行存取
因为多个进程可以同时操作,所以需要进行同步
信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问。

原理

创建

1、创建共享内存
2、进程A连接共享内存,写入数据(这里需要给进程A一个睡眠时间:两个进程同时操作需要同步,进程A写入数据后睡眠一定时间,在这个时间内进程B将数据读取,实现数据交换)
3、进程A断开连接
4、进程B连接共享内存,读取数据
5、进程B断开连接
6、释放公共内存

常用API

头文件

#include <sys/types.h>
#include <sys/shm.h>
//以下几个API都包含以上两个头文件

shmget函数

功能

创建或获取一个共享内存

函数原型

int shmget(key_t key, size_t size, int shmflg);

参数解读

keyftok生成的key标识,标识系统的唯一IPC资源
size需要申请共享内存的大小。在操作系统中,申请内存的最小单位为页,一页是4k字节,为了避免内存碎片,我们一般申请的内存大小为页的整数倍,即以兆为单位
shmflg如果要创建新的共享内存,需要使用IPC_CREAT,IPC_EXCL,后面需要加权限标志,权限标志与文件的读取操作一样。如果是已经存在的,可以使用IPC_CREAT或直接传0(只需获取而不用创建,yi)

返回值

成功时返回一个新建或已经存在的的共享内存标识符,取决于shmflg的参数。失败返回-1并设置错误码。

shmat函数

功能

第一次创建完共享内存时,它还不能被任何进程访问,shmat函数的作用就是用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间,即将共享内存映射进进程中。

函数原型

void *shmat(int shm_id, const void *shm_addr, int shmflg); 

参数解读

shm_id由shmget函数返回的共享内存标识
*shm_addr指定共享内存连接到当前进程中的地址位置,通常为空(为0),表示让系统为我们安排共享内存的地址
shmflg

若指定了SHM RDONLY位,则以只读方式连接此段,否则以读写方式连接此段(输入0即可,表示映射进的共享内存可读可写

返回值

成功返回共享存段的指针(虚拟地址),并且内核将使其与该共享存段相关的shmid_ds(第四个函数的第三个参数)结构中的shm_nattch计数器加1 (类似于引用计数,即内存占用计入总内存) ; 出错返回-1

shmdt函数

功能

当一个进程不需要共享内存的时候,就需要去关联。该函数并不删除所指定的共享内存区,而是将之前用shmat函数连接好的共享内存区脱离目前的进程

函数原型

int shmdt(const void *shmaddr); 

参数解读

*shmaddr:是shmat函数返回的地址指针,只需将其返回值的函数变量名(代码地址)写入即可

返回值

调用成功时返回0,失败时返回-1。

shmctl函数

功能

控制共享内存

函数原型

int shmctl(int shm_id, int command, struct shmid_ds *buf);  

参数解读

shm_idshmget函数返回的共享内存标识符
commandcommand是要采取的操作,它可以取下面的三个值
IPC_STAT把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值
IPC_SET如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
IPC_RMID(常用)删除共享内存段

*bufbuf是一个结构指针,它指向共享内存模式和访问权限的结构(不关心,一般写0

返回值

成功时返回0,失败返回-1并设置错误码。

代码示例

shmw.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>int main()
{key_t key;int shmid;char *shmaddr = NULL;	key = ftok(".",1);//当前目录建立IPCshmid = shmget(key,1024*4,IPC_CREAT|0666);//以可读可写方式开辟一个4兆大小的共享内存if(shmid == -1){printf("create gxdl failed\n");exit(-1);}shmaddr = shmat(shmid,0,0);//将共享内存映射到进程中printf("connect success!\n");strcpy(shmaddr,"hello word!");sleep(5);//因为写入和读取是同步,所以此时执行完写入代码后需等待读取数据后一起关闭共享内存shmdt(shmaddr);//断开连接共享内存shmctl(shmid,IPC_RMID,0);//删除共享内存printf("over\n");return 0;
}

shmr.c

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>int main()
{key_t key;int shmid;char *shmaddr = NULL;	key = ftok(".",1);shmid = shmget(key,1024*4,0);//这里只需找到已经开辟的共享内存,所以参数为0即可if(shmid == -1){printf("create gxdl failed\n");exit(-1);}shmaddr = shmat(shmid,0,0);//映射共享内存printf("connect success!\n");printf("content is %s\n",shmaddr);//将共享内存数据打印出来shmdt(shmaddr);//断开共享内存printf("over\n");return 0;
}

shmw.c程序运行,写入端往共享内存写入数据,并让其等待5s,这5s内shmr.c程序运行,读取端读取共享内存数据并将内容打印出来,5s后两者同时关闭共享内存输出over。

fork函数的补充

功能

系统IPC键值的格式转换函数,系统建立IPC通讯 (消息队列、信号量和共享内存) 时必须指定一个ID值。通常情况下,该id值通过ftok函数得到。

函数原型

key_t ftok( const char * fname, int id );

参数解读

fname就是你指定的文件名(已经存在的文件名),一般使用当前目录
id子序号。虽然是int类型,但是只使用8bits(1-255)

例如

key_t key;
key = ftok(".", 1); //当前文件只需加.

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

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

相关文章

Linux系统通过firewall限制或开放IP及端口

一、查看防火墙状态 1、首先查看防火墙是否开启&#xff0c;如未开启&#xff0c;需要先开启防火墙并作开机自启 systemctl status firewalld开启防火墙并设置开机自启 systemctl start firewalld systemctl enable firewalld一般需要重启一下机器&#xff0c;不然后面做的设…

SHAP - 机器学习模型可解释性工具

github地址&#xff1a;shap/docs/index.rst at master shap/shap (github.com) SHAP使用文档&#xff1a;欢迎使用 SHAP 文档 — SHAP 最新文档 SHAP介绍 SHAP&#xff08;SHapley Additive exPlanations&#xff09;是一种用于解释预测结果的方法&#xff0c;它基于Shapley…

【深度学习】不用Conda在PP飞桨Al Studio三个步骤安装永久PyTorch环境

在 PaddlePaddle AI Studio 中使用 Python 虚拟环境安装 PyTorch 免责声明 在阅读和实践本文提供的内容之前&#xff0c;请注意以下免责声明&#xff1a; 侵权问题: 本文提供的信息仅供学习参考&#xff0c;不用做任何商业用途&#xff0c;如造成侵权&#xff0c;请私信我&am…

stm32定时器输入捕获模式

频率测量 频率测量有两种方法 测频法&#xff1a;在闸门时间T内&#xff0c;对上升沿或下降沿计次&#xff0c;得到N&#xff0c;则评率fxN/T测周法&#xff1a;两个上升沿内&#xff0c;以标准频率fc计次得到N&#xff0c;则频率fx fc/N中界频率&#xff1a;测频法和测周法误…

Python Pyvis库详解:创建交互式网络图

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python Pyvis库详解&#xff1a;创建交互式网络图&#xff0c;文章4000字&#xff0c;阅读大约15分钟&#xff0c;大家enjoy~~ Pyvis是一个基于JavaScript库NetworkX的Pytho…

git-2

1.分离头指针情况下的注意事项 分离头指针指的是变更没有基于某个branch去做&#xff0c;所以当进行分支切换的时候&#xff0c;在分离头指针上产生的commit&#xff0c;很可能会被git当作垃圾清理掉&#xff0c;如果你认为是重要的内容&#xff0c;切记需要绑定分支 2.进一步…

【11月比赛合集】48场可报名的数据挖掘大奖赛,任君挑选!

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 Kaggle&#xff08;9场比赛&#xff09;阿里天池&#xff08;…

基于蛇优化算法优化概率神经网络PNN的分类预测 - 附代码

基于蛇优化算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于蛇优化算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于蛇优化优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

ubuntu借助overlay方案实现重启自动还原

配置重启还原OS 首先&#xff1a;sudo apt install overlayroot 安装一下软件 然后编辑配置文件&#xff1a;/etc/overlayroot.conf * overlayroottmpfs or overlayroottmpfs:PARAMETERS write all changes to a temporary (ram only) backing device A tmpfs mount will …

中职组网络安全B模块-渗透提权2

任务五&#xff1a;渗透提权2 任务环境说明&#xff1a; 仅能获取xxx的IP地址 用户名&#xff1a;test&#xff0c;密码&#xff1a;123456 访问服务器主机&#xff0c;找到主机中管理员名称&#xff0c;将管理员名称作为Flag值提交&#xff1b; Flag:doyoudoyoudo 访问服…

srs的webrtc信令分析

关于webrtc的流信令只有四个 /rtc/v1/publish/&#xff0c;这是推流接口&#xff0c;是推流客户端跟SRS交换SDP的接口 /rtc/v1/play/&#xff0c;这是拉流接口&#xff0c;是拉流客户端跟SRS交换SDP的接口 /rtc/v1/whip/&#xff0c;这也是推流接口&#xff0c;作用是也是交换…

汇编-PUSHFD和POPFD标志寄存器值压栈和出栈

PUSHFD指令将32位EFLAGS寄存器内容压入堆栈&#xff0c; 而POPFD指令则将栈顶单元内容弹出到EFLAGS寄存器 格式&#xff1a;