Linux-共享内存通信
Linux共享存储通信
内容
- 创建共享存储区实现进程通信
机理说明
共享存储区(Share Memory)是Linux系统中通信速度最高的通信机制。该机制中共享内存空间和进程的虚地址空间满足多对多的关系。即一个共享内存空间可以映射多个进程的虚地址空间,一个进程的虚地址空间又可以连接多个共享存储区。当进程间预利用共享存储区通信时,先要在主存中建立一个共享存储区,然后将它附接到自己的虚地址空间。该机制只为进程提供了用于实现通信的共享存储区和对共享存储区进行操作的手段,然而并未提供对该区进行互斥访问及进程同步的措施。
调用函数说明
创建共享内存
shmget(key ,size ,flag)
功能:获得一个内部标识为shmid的共享存储区。
语法:int shmget = int shmget(key_t key ,int size ,int flag);
参数说明:
key 共享存储区关键字,可由用户指定。若使用IPC_PRIVATE则其值由系统产生。
size 存储区大小(字节数)。若存储区定义为字符型,则大小为定义的字符个数;若定义为整型,大小可以用sizeof(int)加以定义
flag 用户设置的标志或访问方式,如0666|IPC_CREAT,表示任意进程皆可读可写
| 操作允许权 | 八进制数 | 操作允许权 | 八进制数 |
|---|---|---|---|
| 用户可读 | 0400 | 小组可写 | 0020 |
| 用户可写 | 0200 | 其它可读 | 0004 |
| 小组可读 | 0040 | 其它可写 | 0002 |
附接共享内存
字符型共享内存:
shmat(int shmid ,char *shmadddr ,int msgflg ,ulong * raddr);
数值型共享内存:
shmat(int shmid ,int *shmadddr ,int msgflg ,ulong * raddr);
语法格式:
字符型共享内存:
viraddr = (char *) shmat (shmid ,shmaddr ,shmflag);
viraddr = (int *) shmat (shmid ,shmaddr ,shmflag);
参数说明:
shmid共享存储区的描述符,可由shmget()的返回值得到。
shmaddr用户提供的共享存储区附接的虚地址。
shmflag规定存储区的操作权限。如,SHM_RND则表示操作系统在必要时舍去地址;SHM_RDONLY则表示只允许读,shmflag为0表示可读可写。
断开共享内存
shmdt(viraddr)
参数说明:
viraddr系统调用shmat()所返回的虚地址。
返回值:
函数被正确调用则返回0,错误返回-1
shmctl(int shmid ,int cmd ,struct shmid_ds * buf);
功能:对共享内存进行操作控制
参数说明:
shmid共享存储区的描述符,可由shmget()的返回值得到。
buf用户级数据结构地址,可为0。
cmd规定的操作类型
| 操作代码 | 含义 |
|---|---|
| IPC_STAT | 返回指定shmid数据结构的状态信息,放置于*buf中,必须有读取允许权 |
| IPC_SET | 设置指定shmid的有效用户和操作存取权 |
| IPC_RMID | 删除指定shmid以及与它相关的共享存储区的数据结构 |
| SHM_LOCK | 在内存中锁定指定的共享存储区,必须是root才能执行 |
shmctl(shmid ,IPC_RMID ,0); //撤销共享内存区
实现思路
send:
- shmget()创建或者获取指定key值的共享内存
- shmat()将该内存附接到自己的虚拟地址空间
- 将消息写入共享内存
- 字符:
- 以追加方式写入,strcat(viraddr ,buffer)
- 以覆盖方式写入,strcpy(viraddr ,buffer)
- 数字:
- 直接赋值
- 操作数组\
- 字符:
- shmdt()断开共享内存
receive:
- shmget()创建或者获取指定key值的共享内存
- shmat()将该内存附接到自己的虚拟地址空间
- 输出信息
- shmdt()断开共享内存
- shmctl()撤销内存
实例
send
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/shm.h>
/*共享内存 share memory 实现的进程通信*/
main()
{
int shmid;
char *viraddr;
char buffer[BUFSIZ];
shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT);
viraddr=(char*)shmat(shmid,0,0);
while(1)
{
puts("Enter some text:");
fgets(buffer,BUFSIZ,stdin);/*从标准输入设备读入一行字符串,stdin是标准输入,C标准库里面的一 个全局变量*/
strcat(viraddr,buffer); /*字符串追加函数*/
if(strncmp(buffer,"end",3)==0)/*比较两个字符串数组*/
break;
}
shmdt(viraddr);
exit(0);
}
receive
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/shm.h>
main()
{
int shmid;
char *viraddr;
shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT);
viraddr=(char*)shmat(shmid,0,0);
printf("Your message is :\n%s",viraddr);
shmdt(viraddr); /*断开连接*/
shmctl(shmid,IPC_RMID,0); /*撤销共享内存*/
exit(0);
}
运行结果

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/shm.h>
/* 父进程与子进程间的通信,子进程写信息到共享内存中,父进程读取该信息
BUFSIZ为全局量定义在<stdlib.h>,8192
使用exit(0)和wait(0)进行同步*/
main()
{
int chld,shmid;
char *viraddr;
char buffer[BUFSIZ];
shmid=shmget(IPC_PRIVATE,BUFSIZ,0666|IPC_CREAT);
viraddr=(char*)shmat(shmid,0,0);
while((chld=fork())==-1);
if(chld==0)
{ /*子进程块*/
while(1)
{
puts("Enter some text:"); /*写信息到共享内存*/
fgets(buffer,BUFSIZ,stdin); /*用户输入信息*/
strcat(viraddr,buffer); /*附接到进程的虚拟空间*/
if(strncmp(buffer,"end",3)==0)
break; /*输入end结束*/
}
exit(0);
}
else
{ /*父进程块*/
wait(0);
printf("Your message is:\n%s",viraddr);
shmdt(viraddr); /*断开共享内存*/
shmctl(shmid,IPC_RMID,0); /*释放共享内存*/
exit(0);
}
}
运行结果

Linux-共享内存通信的更多相关文章
- linux 两个进程通过 共享内存 通信例子
例子1:两个进程通过共享内存通信,一个进程向共享内存中写入数据,另一个进程从共享内存中读出数据 文件1 创建进程1,实现功能,打印共享内存中的数据 #include <stdio.h> # ...
- 【转载】ipcs与Linux共享内存
一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...
- Linux 程序设计1:深入浅出 Linux 共享内存
笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...
- linux 共享内存shm_open实现进程间大数据交互
linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...
- Linux共享内存(二)
Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...
- PHP进程通信基础——信号量+共享内存通信
PHP进程通信基础--信号量+共享内存通信 由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂.由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误.信号量这个名 ...
- Linux 共享内存编程
共享内存允许系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存是通信速度最快的一种IPC. 实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空 ...
- Windows进程间共享内存通信实例
Windows进程间共享内存通信实例 抄抄补补整出来 采用内存映射文件实现WIN32进程间的通讯:Windows中的内存映射文件的机制为我们高效地操作文件提供了一种途径,它允许我们在WIN32进程中保 ...
- linux 共享内存
共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...
- linux使用共享内存通信的进程同步退出问题
两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子: ...
随机推荐
- 第十二节:WebApi自动生成在线Api文档的两种方式
一. WebApi自带生成api文档 1. 说明 通过观察,发现WebApi项目中Area文件夹下有一个HelpPage文件夹,如下图,该文件夹就是WebApi自带的生成Api的方式,如果该文件夹没了 ...
- windows service创建使用整合
C#创建Windows Service(Windows 服务)基础教程 C#winform windows服务程序创建与安装 C#实现WinForm随WINDOWS服务一起启动
- 关于dfs
DFS 关于dfs,我的理解就是深度搜索,找到所有与入口相连的路径,可以用于迷宫求出口,利用递归的思想,进行搜索返回所有值. 比如,给你两个值分别表示迷宫的长和宽,迷宫有一个入口,一个出口,判断能否从 ...
- Jmeter、Postman 、 loadrunner SoapUI 接口测试工具
一. loadrunner 简称 LR 二. Jmeter 1.安装包:apache-jmeter-4.0.tgz 解压.学会此工具的使用 和POSTman 一样的. 2.本机测试:双击apa ...
- “放到桌面”的Servlet实现
复习下Servlet下载文件, 当response把ContentType设置成application/xxxx的时候呢,浏览器会默认启动下载,而不是试图打开. 通过给httpHeader里面加入内容 ...
- HDU 3966 树链剖分后线段树维护
题意: 一棵树, 操作1.$path(a,b)$之间的点权$+k$ 操作2.单点查询 题解: 树链剖分即可,注意代码细节,双向映射 主要是记录一下板子 #include <string.h> ...
- ASP Action函数 如何接收client传递的数据(编辑中。。。)
参看链接:https://www.cnblogs.com/umlzhang/p/3654486.html 我这里总结一下,Action的参数的来源比较多 1.url 2.路由设定 3.post中的内容 ...
- VMware workstation 上克隆CentOS 6.x 系统后网卡无法启动的问题
在日常学习中,我们往往没有足够的物理机资源来搭建多节点的实验环境,一个比较好的解决方案就是利用虚拟机来模拟物理机完成实验. 这样一来,多节点操作系统的部署就可以利用VMware 自带的系统“克隆”功能 ...
- 插入MongoDB文档:mongo控制台查看插入到MongoDB文档中的内容
const MongoClient = require('mongodb').MongoClient; const assert = require('assert'); const url = 'm ...
- curl常用命令备忘
#####(输出请求头信息) curl -I xxx-Pro:test xxx$ curl -I https://www.baidu.com/ HTTP/1.1 200 OK Accept-Range ...