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)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子: ...
随机推荐
- 【转】Steam 开发者收入计算
全部说的话有点复杂,捡要点说说: 假设收入100美刀. 假设美区收入50刀,非美区(在美国以外的地区,俄罗斯,中国等等其他国家)收入50刀. 1.分给steam 30% 剩下70刀. 开发者所得美区收 ...
- 非常好用的sersync同步工具
作者:邓聪聪 常用同步工具sync的进阶软件 服务端的配置: uid = rsync gid = rsync port = use chroot = on max connections = time ...
- 在django admin中添加自定义视图
来自https://blog.csdn.net/qq_35753140/article/details/84881757 django admin提供了完善的用户管理和数据模型管理,方便实用.研究 ...
- python学习第34天
# 互斥锁# 进程之间的数据共享 # 关于数据安全的问题# 进程池(自己了解,后面线程部分还会讲) # from multiprocessing import Pool# 线程的概念 (面试的重点)# ...
- ajax 调用 .net core WebAPI,报错 400 (Bad Request) Unexpected character encountered while parsing value
此文由博主前两天的提问及 dudu 的回答整理,地址:https://q.cnblogs.com/list/myquestion 情况说明 基于 .net core 写了一个 Web API,用 po ...
- AngularJS指令基础(一)
AngularJS指令基础(一) 1.什么是指令:粗暴的理解就是,自定义HTML标签.专业理解是指,angularJS扩展具有自定义功能的HTML元素的途径. 2.什么时候用到指令:需求是变化的.多样 ...
- vscode插件解析-BookMark
BookMark (书签):在编辑器中标记行并轻松跳转到它们. commands 书签:Toggle 标记/取消标记带书签的行 书签:Jump to Next 将光标向前移动到下面的书签 书签: ...
- 提高github代码下载速度的小技巧
1.打开如下路径: C:\Windows\System32\drivers\etc 2.将此处的HOSTS文件复制到其他地方,比如桌面.(此处大概率是没有编辑权限的) 3.用记事本打开HOSTS文件, ...
- http 响应状态码介绍
- python-shutil学习
shutil:高级的 文件.文件夹.压缩包 处理模块 1. shutil.copyfileobj(fsrc, fdst[, length])(copyfileobj方法只会拷贝文件内容)将文件内容拷贝 ...