c++ fork 进程时 共享内存_c/c++ Linux 进程间通信------共享内存

1. 什么是共享内存

共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言函数malloc分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。

个人理解:在物理内存上有一块空间,不同的进程通过页表将其映射到自己的虚拟地址空间,返回一个地址,通过这个地址可以访问到那一块内存空间,此内存空间为共享内存;

2. 原理

下图中红线表示不同进程将自己的地址空间映射到不同物理内存中,各自进行自己的任务,不同进程之间独立工作

不同进程通过共享内存进行通信:

在物理内存上开辟一块空间,称为共享内存

不同进程将这块共享内存连接到自己的地址空间

不同进程以各自地址空间的虚拟地址通过页表找到共享内存,通过向共享内存中写数据和读数据实现进程间通信

fe6b0d8f27c6f05588a632ecf6f158d7.png

3. 共享内存的特点

以传送数据为目的

所有进程间通信中速度最快的一种方式(例:进程一向共享内存传送数据,进程二能够立马看见传送的数据,少了若干次拷贝)

共享内存生命周期随内核

共享没有自带同步或互斥,由用户来维护共享内存

信号量+共享内存通常结合在一起使用,信号量用来同步对共享内存的访问

4. 共享内存的操作

共享内存的创建

#include

#include

//如果共享内存不存在,创建共享内存,如果存在就打开共享内存

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

//返回值:成功返回共享内存的标识符,失败返回-1

参数:共享内存的关键字key

共享内存的标识符,获取方法和消息队列 key的方法一致,也可认为key就是共享内存的名字

参数:共享内存的大小size:

由你自己指定,一般指定为4k的倍数(内存4k为一页)

参数:共享内存的访问权限shmflg

共享内存的权限,它与文件的访问权限一样

IPC_CREAT:创建新的共享内存。

IPC_EXCL:与IPC_CREAT一同使用,表示如果要创建的共享内存已经存在,则返回错误。 IPC_NOWAIT:读写共享内存要求无法满足时,不阻塞

0:如果是打开文件,即文件已存在,写0

共享内存的查看

命令: ipcs -m

2bfe66a46324d407159c1f1cddfd88d0.png

共享内存的挂载

#include

#include

//将共享内存链接到进程地址空间

void *shmat(int shmid, const void *shmaddr, int shmflg);

//返回值:失败返回NULL,成功返回一个指针,为地址空间的虚拟地址,并且连接数加1(nattch)

参数:共享内存的标识符shmid

shmget的返回值

参数:指定连接进程地址空间的地址shmaddr

共享存储段连接到调用进程的哪个地址上与addr参数以及在flag中是否指定SHM_RND位有关

如果addr为0,则此段连接到由内核选择的第一个可用地址上。这是推荐的使用方式。

如果addr非0,并且没有指定SHM_RND,则此段连接到addr所指定的地址上。

如果addr非0,并且指定了SHM_ RND,则此段连接到(shmaddr -(shmaddr % SHMLBA))所表示的地址上。SHM_RND命令的意思是取整。SHMLBA的意思是低边界地址倍数,它总是2的乘方。该算式是将地址向下取最近1个SHMLBA的倍数。

注:除非只计划在一种硬件上运行应用程序(这在当今是不大可能的),否则不应指定共享段所连接到的地址。所以一般应指定addr为0,以便由内核选择地址

参数:共享内存的权限shmflg

shmflg = SHM_RDONLY,表示连接操作作用来只读共享内存

共享内存的卸载

#include

#include

//将共享内存与当前连接进程脱离

int shmdt(const void* shmaddr)

//返回值:成功返回0,失败返回-1

//参数:由shmat返回的指针

//注意:将共享内存与进程脱离不等于删除共享内存

共享内存的控制

#include

#include

//shmctl系统调用对shmid标识的共享内存执行cmd操作

//返回值:成功返回0,失败返回-1

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

参数:共享内存的表示符shmid

shmget的返回值

参数:将要采取的操作cmd

选项 说明

IPC_STAT 把shmid_ds结构中的数据设置为共享内存的当前关联值

IPC_SET 在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数 据结构中给出的值

IPC_RMID 删除共享内存

参数:保存共享内存的模式状态和访问权限的数据结构buf

共享内存的一些属性,填NULL

服务端客户端实例

comm.h

#ifndef __COMM_H__

#define __COMM_H__

#include

#include

#include

#define PATHNAME "."

#define PROJ_ID 0x6666

int createShm(int size);//创建共享内存

int getShm(int size);//获取共享内存

int destoryShm(int shmid);//销毁共享内存

#endif

comm.c

#include "comm.h"

static int commShm(int size,int flags)//创建共享内存

{

key_t key = ftok(PATHNAME,PROJ_ID);

if(key < 0){

perror("ftok");

return -1;

}

int shmid = shmget(key, size, flags);

if(shmid < 0){

perror("shmget");

return -2;

}

return shmid;

}

int createShm(int size)

{

return commShm(size, IPC_CREAT | IPC_EXCL);

}

int getShm(int size)//获取共享内存

{

return commShm(size, IPC_CREAT);

}

int destoryShm(int shmid)//销毁共享内存

{

if(shmctl(shmid, IPC_RMID,NULL) < 0){

perror("shmctl");

return -3;

}

}

server.c

#include "comm.h"

int main()

{

int shmid = createShm(4096);//创建共享内存

char* addr = (char*)shmat(shmid,NULL,0);//将共享内存进行挂接

int i=0;

while(i++ < 26){

printf("client:%s

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

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

相关文章

云服务器个人入门主机对比和分析

最近阿里云的云服务器快到期了&#xff0c;看看了市场上的各大云主机&#xff0c;然后进行了整理和对比希望对初次买云主机的用户有帮助 阿里云 学生主机腾讯云 学生主机百度云 学生主机华为云金山云滴滴云 DC2云服务器品牌类型CPU内存带宽硬盘价格所需用户阿…

[html] const nums1 = [1, 2, 2, 1], nums2 = [2] 交集是什么?

[html] const nums1 [1, 2, 2, 1], nums2 [2] 交集是什么&#xff1f; let a [1, 2, 2, 1]; let b [2]; let aSet new Set(a); let bSet new Set(b);let intersection Array.from(new Set(a.filter(v > bSet.has(v)))) console.log(intersection); // [2]个人简介 …

数据结构之栈实现中缀转后缀并计算结果

一.中缀变后缀过程分析 给定一个中缀,最后变为后缀的过程其实并不算复杂,下面分析一下过程: 1. 首先面对一个中缀表达式,我们需要两个栈,一个用来存放运算符,即符号栈 operatorstack,一个用来存放数字,运算符,即数字栈 numStack 2. 开始扫描中缀表达式 3.遇到操作数时,我们直接…

TreeView 小技巧

1、在把treeview的check事件给封了之后&#xff0c;在双击的情况下仍然会选中。这个要通过处理消息来解决。 解决&#xff1a; 在调用的时候将这个事件给过滤掉 if (e.Node.ForeColor Color.Gray) e.Cancel true; 自定义treeview中加入以下方法 protected ove…

python爬取新闻网站内容_python爬虫案例:抓取网易新闻

此文属于入门级级别的爬虫&#xff0c;老司机们就不用看了。 本次主要是爬取网易新闻&#xff0c;包括新闻标题、作者、来源、发布时间、新闻正文。 首先我们打开163的网站&#xff0c;我们随意选择一个分类&#xff0c;这里我选的分类是国内新闻。然后鼠标右键点击查看源代码&…

PHPRedis教程之geo

前言 支持 GEO 系列命令的 Redis 版本从 3.2.0 起开始才可以使用&#xff0c;所以之前版本就不要想了。 函数列表 geoadd - 将指定的地理空间项&#xff08;纬度&#xff0c;经度&#xff0c;名称&#xff09;添加到指定的键&#xff0c; 数据作为有序集存储在 Redis 中。 GEOA…

如何查看QQ和微信查看授权过那些应用?

平时生活中&#xff0c;要登录一些网站或者app时&#xff0c;为了省事儿&#xff0c;都用第三方登录&#xff0c;登录是简单快捷了一些 时间长了,授权过的那些应用都不知道了&#xff0c;甚至一些应用你没用去授权权限也一直开放给别人网站的 所以为了自己帐号的安全还是有必…

[html] 说说你对H5的SharedWorker的理解,它有什么运用场景?

[html] 说说你对H5的SharedWorker的理解&#xff0c;它有什么运用场景&#xff1f; 一种特定类型的 worker&#xff0c;可以从几个浏览上下文中访问&#xff0c;例如几个窗口、iframe 或其他 worker。多个标签页之间通信个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后…

Spring 注解AOP 入门

XML <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns:context"http://www.springframework.org/sche…

python常用函数的用法_python3 文件操作常用函数用法示例

1. file.close() 关闭文件。关闭后文件不能再进行读写操作&#xff0c;需要重新打开才能进行读写。f open(demo.text , r) # 使用只读方式打开文本 print(f.read()) # 打印demo.text文件内容 f.close() # 关闭文件 2. file.flush() 将缓存区中的数据立刻写入文件&#xff0c;同…

[html] 制作页面时,前端如何适应各种异形屏?

[html] 制作页面时&#xff0c;前端如何适应各种异形屏&#xff1f; 主要内容区域大小固定&#xff0c;固定在页面中间&#xff0c;两边可伸缩 width:1200px; margin:0 auto;个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很…

awk的妙用

终端形式有人说awk的优势在于可以个性化输出命令&#xff0c;这么说来太抽象了&#xff0c;假如我们查看占用6379端口的进程信息。 lsof -i:6379 输出结果&#xff1a; COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME redis-ser 17474 root 6u IPv6 71242 …

追求真实

是选择在迷茫中生活然后死去 还是选择追求真实&#xff0c;在追求的路上死去。 两种方式共同点是死去的时候都是迷茫的。不得不说是生命的悲剧&#xff0c;不过也可以说是生命的精彩转载于:https://www.cnblogs.com/cuihongyu3503319/archive/2011/08/07/2130204.html

C# ASP.NET MVC 图片上传的多种方式(存储至服务器文件夹,阿里云oss)

图片上传时我们进场用到的一个功能今天将他整理了一下写了个demo希望对大家有用 该demo分为如下 1.上传至至服务器文件夹 2.上传至阿里云oss 3.百度webupload上传图片 效果图如下: 首先讲解一下后台代码 (1)上传至服务器存储 using System; using System.Collections; u…

[html] 写一个布局,当页面滚动一定高时,导航始终固定在顶部,反之恢复原位

[html] 写一个布局&#xff0c;当页面滚动一定高时&#xff0c;导航始终固定在顶部&#xff0c;反之恢复原位 使用粘性定位&#xff0c;position:sticky 记得使用的时候父元素不能使用overflow:hidden和overflow:auto属性&#xff0c;而且必须要指定top/left/bottom/right中任…

java变量命名规则_浅谈JAVA开发规范与开发细节(上)

开发团队在开发过程中&#xff0c;由于每个人的开发习惯&#xff0c;以及对于技术的理解深浅程度不一&#xff0c;往往一个项目在开发过程中&#xff0c;代码的质量&#xff0c;代码的风格都不尽相似&#xff0c;所以有一份适合团队的代码规范是非常有必要的&#xff0c;而一个…

使用Moles对静态方法做UnitTest

我们在开发&#xff0c;有时遇到一些Legcy代码&#xff0c;然后需要对它们进行UnitTest。UnitTest的重要性在这里不再说了。但是发现某些Class中有些方法是Static的&#xff0c;按以往的方法我们需要用Extact Interface 方法 从那个需要测试的Class&#xff0c;然后使用 IOC /D…

Charles

安装 https://www.jianshu.com/p/cb744a4c0344 https://blog.csdn.net/qq_28831197/article/details/81196571 使用说明&#xff1a; 来源&#xff1a;https://www.jianshu.com/p/73b134559c76 过滤网络请求 通常情况下&#xff0c;我们需要对网络请求进行过滤&#xff0c;只监…

.NET Core Docker使用初入篇

本篇内容如何在CentOS上安装Docker服务器与工具准备安装Docker更新系统安装Docker源设置Docker开机启动启动Docker使用Docker运行一个.NET Core 例子.net core 例子拉取.net core 例子停止.net core 例子启用其他如何在CentOS上安装Docker 服务器与工具准备 首先我们需要一个…

[html] 写一个布局,当页面滚动一定高时,导航始终固定在顶部,反之恢复原位

[html] 写一个布局&#xff0c;当页面滚动一定高时&#xff0c;导航始终固定在顶部&#xff0c;反之恢复原位 使用粘性定位&#xff0c;position:sticky 记得使用的时候父元素不能使用overflow:hidden和overflow:auto属性&#xff0c;而且必须要指定top/left/bottom/right中任…