共享内存通信

共享内存通信方式是一种最高效的通信方式,是直接通过开辟内存空间进行映射后用于直接读写的

内存块,大小由用户自己固定开辟(在系统可行范围内),可用于亲缘间的通信,也可用于非亲缘间的通信,比较灵活,缺点是只仅限与在同一个操作系统内进行通信。

所以就需要某些函数进行对共享内存的申请,使用以及删除等操作,我们利用亲缘间 的通信举例子。

步骤:

1:申请共享内存

函数原型如下:

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

参数解释

key: 可以通过ftok()函数进行获得,也可以直接使用IPC_PRIVATE作为参数,默认创建一个键值固定的私有空间作为映射内存,

size :用户自定义申请映射空间的大小,单位为字节

shmflg :代表权限,一般为 IPC_CREAT | 0664,创建成功后返回共享内存的ID号,shmid

2:创建好映射的内存后进行地址的映射

函数原型如下:

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

参数解释:

shmid: 在上一步创建内存后被返回,直接使用

shmaddr : 一般默认为NULL,表示系统自动映射的地址,若需自定义,放入需要映射的地址即可

shmflg :  代表权限,0为读写权限,1为写权限,这里选0

正确返回映射后的用户空间首地址,错误返回(void*)-1,

3:使用fork函数创建子进程

函数原型:

pid_t fork(void);

成功创建返回子进程的 pid  ,失败返回-1

重点:

共享内存的代码需要放在创建子进程代码段之前,由于利用fork 函数创建的进程会拷贝原有的代码,变量等等,所以需在创建共享内存之后创建子进程。

接下来我们自己规定利用子进程进行内存的写入,父进程对内存进行读取,达到通信的目的。

子进程主要代码

char buf[20]={0};while(1){fgets(buf,sizeof(buf),stdin);if(strncmp(buf,"quit",4)==0)break;strcpy(q,buf);memset(buf,0,sizeof(buf));}

这里利用fgets函数从终端读取字符到buf中,再使用strcpy函数对共享内存进行写入,如果写入quit代表结束写入,退出程序。

父进程主要代码

while(1){if(strncmp(q,"quit",4)==0)break;printf("get------%s\n",q);sleep(1);}wait(NULL);exit(0);

使用strcmp函数判断是否读取到quit字符串,读取到就退出,并对子进程进行回收后退出。

我们上述只是完成了对共享内存的读写操作,由于共享内存是由内存映射到用户区后进行使用的,所以为了不占用内存资源还需要在对共享内存进行写入读取操作后进行回收操作

4:使用shmdt函数取消共享内存的映射

int shmdt(const void *shmaddr);

参数解释:

shmaddr : 映射到用户区的首地址

成功取消返回0,错误返回-1;

5 :使用shmctl 函数对共享内存进行删除操作

函数原型:

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

参数解释:

shmid :共享内存ID号

cmd :选择所需要的操作,删除操作使用 IPC_RMID

*buf :NULL

以上步骤便是对共享内存的创建,使用,删除操作,全部代码如下:

#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{ pid_t p;key_t key;if(-1==(key=ftok("1.txt", 21)))                 //获取key值{perror("ftok failed\n");exit(-1);}printf("key=%#x\n",key);int shmid = shmget(key, 1024, 0644 | IPC_CREAT);if(shmid == -1){perror("shmget");return-1;}printf("shmid=%d\n",shmid);char *q=NULL;if((void*)-1==(q=shmat(shmid,NULL,0)))   //映射内存{perror("shmat failed\n");exit(-1);}p=fork();if(p==0)                                                  //子进程{char buf[20]={0};while(1){fgets(buf,sizeof(buf),stdin);if(strncmp(buf,"quit",4)==0)break;strcpy(q,buf);memset(buf,0,sizeof(buf));}if(-1==shmdt(q))                        //取消映射{perror("shmdt failed\n");exit(-1);}if(-1==shmctl(shmid,IPC_RMID,NULL))      //删除映射{perror("shmctl failed\n");exit(-1);}exit(0);}else                                //父进程{while(1){if(strncmp(q,"quit",4)==0)break;printf("get------%s\n",q);sleep(1);}wait(NULL);exit(0);}return 0;
}

使用共享内存进行亲缘间通信相关推荐

  1. 共享内存原理及实现通信过程

    共享内存原理及实现通信过程 共享内存的概念及创建过程 共享内存的使用函数 使用共享内存完成通信 共享内存的概念及创建过程 一. 共享内存的概念 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它 ...

  2. QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QSharedMemory共享内存实现进程间通讯(IPC)及禁止程序多开     本文地址:h ...

  3. 共享内存进程线程混合通信

    多线程共享内存混合编程 /*threadWrite线程向共享内存写数据,threadRead线程从共享内存读数据*/ /*读线程必须等待写线程执行完才开始*/ #include <stdio.h ...

  4. 共享内存实现进程间大数据的交换

    引言 进程间的数据交换和共享是一种非常重要和实用的技术.大.中型软件的开发设计多是由众多程序设计人员的合作完成,通常一个程序设计人员只负责其中一个或几个模块的开发,这些模块可以是动态链接库也可以是应用 ...

  5. linux进程间通信:system V 信号量和共享内存实现进程间同步

    关于信号量和共享内存的相关描述已经在前几篇提到过: 信号量:即内核维护的一个正整数,可以使用内核提供的p/v接口进行该正整数的+/-操作,它主要用来表示系统中可用资源的个数,协调各个进程有序访问资源, ...

  6. Windows上C++使用共享内存进行进程间通讯

    共享内存 (也叫内存映射文件) 主要是通过映射机制实现的 , Windows 下进程的地址空间在逻辑上是相互隔离的 , 但在物理上却是重叠的 ; 所谓的重叠是指同一块内存区域可能被多个进程同时使用 , ...

  7. oracle ipcs mt,Oracle Study之--IPCS管理共享内存

    Oracle Study之--IPCS管理共享内存 Unix/linux下的共享内存.信号量.队列信息管理 在unix/linux下,经常有因为共享内存.信号量,队列等共享信息没有干净地清除而引起一些 ...

  8. 进程间的通信——共享内存

    下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...

  9. 删除共享内存_进程通信专题之 共享内存

    什么是共享内存呢? 共享内存是被多个进程共享一部分物理内存,共享内存是进程间共享数据最快的办法,因为一个进程向共享内存中写了数据,那么共享的这个区域的所有进程就可以立刻看到这里的数据. 共享内存有什么 ...

最新文章

  1. SQL语法中drop,delete与truncate的区别
  2. javascript DOM innerHTML createElement createTextNode
  3. Virtualbox虚机无法启动因断电
  4. 创新实训团队记录:为BR-MTC问题设计一个近似算法
  5. 二叉排序树的中序遍历规律_看懂这篇文章,玩转二叉查找树
  6. CodeSmith实用技巧(八):生成的代码输出到文件中
  7. 有奖问题征集|向大咖Scott 发问,好礼等你领!
  8. c 指针打印变量_C程序打印不同类型的指针变量的大小。
  9. CUDA中并行规约(Parallel Reduction)的优化
  10. element引入的组件大小高度不对_ElementUI 在 按需引入时定义 default size?
  11. 建站基础知识之HTML 是何方神圣?
  12. MT7621完美支持32M SPI Flash(W25Q256) 修复 soft reset fail
  13. STM32入门教程第一讲
  14. 微信接入之获取用户头像
  15. 2019年360笔试
  16. html如何设置自动点击事件,html 如何设置打开网页时自动触发按钮的单击事件
  17. 本质与现象:本质与现象
  18. luogu P4643 [国家集训队]阿狸和桃子的游戏
  19. 最近很多人问我:saiku下载不下来
  20. 1220 -- 青蛙过河

热门文章

  1. 股市入门篇——什么是熊市?
  2. php 如何计算上网流量,手机流量是怎么计算上网流量的?
  3. AtCoder Grand Contest 004 A - Divide a Cuboid 题解
  4. 实例6:用 * 输出字母C分行输出
  5. PS-InSAR公路互通变形监测
  6. 打印formdata的值
  7. 基于Java EE新闻管理系统的设计与实现
  8. 移动机器人技术(8) 麦克纳姆轮全向移动机器人
  9. 【DM】达梦DCA培训及考试认证
  10. 怎么解决在微信中不能直接下载APP(APK)的方案