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-共享内存通信的更多相关文章

  1. linux 两个进程通过 共享内存 通信例子

    例子1:两个进程通过共享内存通信,一个进程向共享内存中写入数据,另一个进程从共享内存中读出数据 文件1 创建进程1,实现功能,打印共享内存中的数据 #include <stdio.h> # ...

  2. 【转载】ipcs与Linux共享内存

    一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...

  3. Linux 程序设计1:深入浅出 Linux 共享内存

    笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...

  4. linux 共享内存shm_open实现进程间大数据交互

    linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...

  5. Linux共享内存(二)

    Linux共享内存编程实例 原文链接:http://blog.csdn.net/pcliuguangtao/article/details/6526119 /*共享内存允许两个或多个进程进程共享同一块 ...

  6. PHP进程通信基础——信号量+共享内存通信

    PHP进程通信基础--信号量+共享内存通信 由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂.由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误.信号量这个名 ...

  7. Linux 共享内存编程

    共享内存允许系统内两个或多个进程共享同一块内存空间,并且数据不用在客户进程和服务器进程间复制,因此共享内存是通信速度最快的一种IPC. 实现的机制简单描述如下:一个进程在系统中申请开辟了一块共享内存空 ...

  8. Windows进程间共享内存通信实例

    Windows进程间共享内存通信实例 抄抄补补整出来 采用内存映射文件实现WIN32进程间的通讯:Windows中的内存映射文件的机制为我们高效地操作文件提供了一种途径,它允许我们在WIN32进程中保 ...

  9. linux 共享内存

    共享内存是最高效的IPC机制,因为它不涉及进程之间的任何数据传输.这种高效带来的问题是,我们必须用其他手段来同步进程对共享内存的访问,否则会产生竞态条件.所以,共享内存通常和其他进程间通信方式一起使用 ...

  10. linux使用共享内存通信的进程同步退出问题

    两个甚至多个进程使用共享内存(shm)通信,总遇到同步问题.这里的“同步问题”不是说进程读写同步问题,这个用信号量就好了.这里的同步问题说的是同步退出问题,到底谁先退出,怎么知道对方退出了.举个例子: ...

随机推荐

  1. 实现Map接口(hash原理)

    闲来无事,就实现一个简单的map来练练手吧! HashMap的底层实现主要是基于数组和链表来实现的,HashMap中通过key的hashCode来计算hash值的,由这个hash值计算在数组中的位置, ...

  2. 072、一文搞懂各种Docker网络 (2019-04-17 周三)

    参考https://www.cnblogs.com/CloudMan6/p/7587532.html   前面各个小节我们学习了 Docker Overlay .Macvlan .Flannel.We ...

  3. [译]Ocelot - Rate Limiting

    原文 Ocelot支持对上游做访问限流,这样就可以保证下游不要负载太大了. 如果要启用访问限流,需要做如下配置: "RateLimitOptions": { "Clien ...

  4. 使用Ueditor编辑器上传图片总结;

    今天使用Ueditor编辑器上传图片一直出问题,在网上找了多种方法,最后总结如下: Ueditor编辑器是百度开发的编辑器,要在jsp页面添加Ueditor编辑器,需要以下几步: (1)到 http: ...

  5. python之map,filter

    map和filter是python里面比较重要的BIF,map的主要作用就是对集合里面的每一个元素进行处理,filter的作用就是过滤集合,具体功能如下 t =lambda x:x%2 list(fi ...

  6. Zabbix 添加端口监控链接

    zabbix 添加端口监控 连接数: zabbix  配置  添加 监控项: 其他检测 方式也是 示例: zabbix 客户端配置文件添加: 编辑 zabbix_agentd.conf  添加  端口 ...

  7. IIS部署项目

    控制面板\所有控制面板项\管理工具-->Internet 信息服务(IIS)管理器 随便填个名称,项目的路径,选择一个新的端口.

  8. Spring Boot系列(二) Spring Boot 之 REST

    Rest (Representational Stat Transer) 是一种软件架构风格. 基础理论 架构特性 性能 可伸缩 简化的统一接口 按需修改 组件通信透明 可移植 可靠性 架构约束 C/ ...

  9. Spring Cloud 2-Hystrix DashBoard仪表盘(五)

    Spring Cloud  Hystrix DashBoard  1.监控系统配置 pom.xml application.yml Application.java 2.被监控服务配置 pom.xml ...

  10. 极客时间-左耳听风-程序员攻略-Linux系统、内存和网络

    程序员练级攻略:Linux系统.内存和网络 Linux 系统相关 Red Hat Enterprise Linux 文档 . Linux Insides ,GitHub 上的一个开源电子书,其中讲述了 ...