目录

★ key值说明

★ shmget函数

★ shmat函数

★ shmdt函数

★ shmctl函数

★ 操作说明

★ IPC相关指令


简介:共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息

★ key值说明

key值获取:key值就是通信的进程双方互相协议好的,作为在内核里找到它们专属的信息交互的空间。通常用ftok函数来获取。比如:在一家餐厅中,有编号为a b c d e五张桌子,张三约了小美在c号桌一起吃饭,那么小美赴约直接到c号桌与张三共同用餐。如果张三和小美没有协议好在c桌用餐,那么他们就可能不会在同一张做桌子上吃饭,就完成不了这次约会。

key_t ftok(const char *pathname, int proj_id);

pathname:已经有存在的文件路径或文件名,一般使用当前目录;

proj_id: 子序号。虽然为int型,但是只有8byte被使用,也就是0—255;

返回值:成功返回key值,失败返回-1;

示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>int main()
{
//      key_t ftok(const char *pathname, int proj_id);key_t key = ftok("demo1.c",1);if(key == -1){printf("error!\n");}printf("key:%d\n",key);return 0;
}编译成功,获取到key值:
dhw@dhw-virtual-machine:~/shm$ ./a.out
key:16989618

★ shmget函数

shmget函数:创建共享内存,获得共享内存的标识符,用shmid来接收标识符

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

key_t key:ftok函数的返回值或者使用IPC_PRIVATE,一般使用ftok函数的返回值;

size_t size:(自定义)共享内存的大小,一般以‘兆’为单位,比如1024或者1024*n;

int shmflg:访问权限,结合IPC_CREAT使用。注意:在shmat函数中作为映射内容,一般写0,表示读写权限。

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

示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main()
{
//      key_t ftok(const char *pathname, int proj_id);key_t key = ftok("demo1.c",1);if(key == -1){printf("error!\n");}printf("key:%d\n",key);//      创建共享内存,获取共享内存标识码
//      int shmget(key_t key, size_t size, int shmflg);int shmid = shmget(key,1024,IPC_CREAT|0666);if(shmid == -1){printf("shmid error!\n");return -1;}printf("shmid:%d\n",shmid);return 0;
}编译成功,获取到共享内存标识码
dhw@dhw-virtual-machine:~/shm$ ./a.out
key:16989623
shmid:15

★ shmat函数

shmat函数:连接共享内存,将共享内存映射到用户空间的地址当中去

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

int shmid:共享内存的标识符,也就是shmget函数的返回值;

comst void*shmaddr:映射到的地址,一般写NULL,系统自动完成映射;(使用时须单独定义char*shmaddr来接收shmat函数的返回值)

int shmflg:通常为0,表示共享内存可读可写;或者SHM_RDONLY,表示共享内存只读;

返回值:成功返回共享内存映射到进程中的地址,失败返回-1。

代码示例:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>int main()
{
//      key_t ftok(const char *pathname, int proj_id);key_t key = ftok("demo1.c",1);if(key == -1){printf("error!\n");}printf("key:%d\n",key);//      创建共享内存,获取共享内存标识码
//      int shmget(key_t key, size_t size, int shmflg);int shmid = shmget(key,1024,IPC_CREAT|0666);if(shmid == -1){printf("shmid error!\n");return -1;}printf("shmid:%d\n",shmid);//      连接共享内存,将共享内存映射到用户空间的地址当中去
//      void *shmat(int shmid, const void *shmaddr, int shmflg);char *shmaddr = shmat(shmid,NULL,0);strcpy(shmaddr,"HappyNewYear!");//在映射到的地址空间中写入内容sleep(5);//等待用户读取内容return 0;
}

★ shmdt函数

shmdt函数: 将进程中的地址映射删除,不会删除内核。就是当一个进程不需要共享内存的时候,就可以使用shmat函数将他从进程地址空间中脱离,并不会删除内核里面的共享内存对象。

int shmdt(const void *shmaddr);

comst void*shmaddr:共享内存映射后的地址;

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

代码示例:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>int main()
{
//      key_t ftok(const char *pathname, int proj_id);key_t key = ftok("demo1.c",1);if(key == -1){printf("error!\n");}printf("key:%d\n",key);//      创建共享内存,获取共享内存标识码
//      int shmget(key_t key, size_t size, int shmflg);int shmid = shmget(key,1024,IPC_CREAT|0666);if(shmid == -1){printf("shmid error!\n");return -1;}printf("shmid:%d\n",shmid);//      连接共享内存,将共享内存映射到用户空间的地址当中去
//      void *shmat(int shmid, const void *shmaddr, int shmflg);char *shmaddr = shmat(shmid,NULL,0);strcpy(shmaddr,"HappyNewYear!");//在映射到的地址空间中写入内容sleep(5);//等待用户读取内容//      int shmdt(const void *shmaddr);shmdt(shmaddr);//删除映射地址return 0;
}

★ shmctl函数

shmctl函数: 删除内核中共享内存对象

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

int shmid:要删除的共享内存的标识符;

int cmd:IPC_STAT(获取对象属性), IPC_SET(设置对象属性), IPC_RMID(删除对象);

struct shmid_ds *buf:指定IPC_STAT(获取对象属性)和IPC_SET(设置对象属性)时用来保存或者设置的属性。不需要时该参数直接写0;

代码示例:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>int main()
{
//      key_t ftok(const char *pathname, int proj_id);key_t key = ftok("demo1.c",1);if(key == -1){printf("error!\n");}printf("key:%d\n",key);//      创建共享内存,获取共享内存标识码
//      int shmget(key_t key, size_t size, int shmflg);int shmid = shmget(key,1024,IPC_CREAT|0666);if(shmid == -1){printf("shmid error!\n");return -1;}printf("shmid:%d\n",shmid);//      连接共享内存,将共享内存映射到用户空间的地址当中去
//      void *shmat(int shmid, const void *shmaddr, int shmflg);char *shmaddr = shmat(shmid,NULL,0);strcpy(shmaddr,"HappyNewYear!");//在映射到的地址空间中写入内容sleep(5);//等待用户读取内容//      int shmdt(const void *shmaddr);shmdt(shmaddr);//删除映射地址//      int shmctl(int shmid, int cmd, struct shmid_ds *buf); shmctl(shmid,IPC_RMID,0);printf("quit\n");return 0;
}

★ 操作说明

以上demo1整个流程看作是”写端“,那么将demo2看作”读端“,在读端中不需要在设置共享内存的权限以及关闭映射地址和释放共享内存,因为在demo1中已经设置好共享内存的访问权限以及在写入内容后已经设置了sleep(5)的时间等待用户读取地址内容,读取完后便使用的shmdt和shmctl来关闭映射地址和释放共享内存。编译时,在执行写端内容后5秒内(自己设定时间),执行读端,因为在5s后写段就会关闭映射地址。

demo2示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main()
{key_t key = ftok("demo1.c",1);int shmid = shmget(key,1024,0);//‘写端已设共享内存权限,此处0’if(shmid == -1){printf("shmid error!\n");exit(-1);}char *shmaddr = shmat(shmid,NULL,0);printf("shmat success!\n");printf("shmaddr:%s\n",shmaddr);//直接读取已经写入的内容printf("quit\n");return 0;
}

★ IPC相关指令

ipcs :显示消息队列,共享内存,信号量通信的相关数据;

ipcs -m:只显示共享内存信息;

ipcrm -m:删除共享内存标识符。

Linux进程间通信:共享内存(shm)相关推荐

  1. 【Linux】Linux进程间通信——共享内存/消息队列/守护进程

    文章目录 进程间通信--共享内存/守护进程 一, 共享内存 1. 共享内存概念 2. 共享内存使用 1. 共享内存使用步骤 2. 共享内存操作函数 3. 共享内存常用操作命令 4. 共享内存使用示例: ...

  2. Linux --进程间通信--共享内存

    一.共享内存 共享内存是最高效的通信方式,因为不需要一个进程先拷贝到内核,另一个进程在存内核中读取. 二. ipcs -m 查看共享内存 ipcrm -m 删除共享内存 三.主要函数 shmget 创 ...

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

    1. 什么是共享内存 共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是 ...

  4. linux如何创建共享内存,linux实现共享内存同步的四种方法

    https://blog.csdn.net/sunxiaopengsun/article/details/79869115 本文主要对实现共享内存同步的四种方法进行了介绍. 共享内存是一种最为高效的进 ...

  5. Linux基础入门--进程间通信--共享内存

    Linux基础入门--进程间通信--共享内存 1.共享内存IPC原理 2.共享内存管理 1.共享内存IPC原理 共享内存进程间通信机制主要用于实现进程间大量的数据传输,共享内存是在内存单独开辟的一段内 ...

  6. Linux下进程间通信--共享内存:最快的进程间通信方式

    内存共享最新整理: Linux下进程间通信-共享内存 - 码到城攻共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式https://www.codecomeon.com/posts/109/ ...

  7. 进程间通信(IPC)之内存映射mmap和共享内存shm

    一.共享内存shm 1 概念:多个进程的地址空间都映射到同一块物理内存,这样多个进程都能看到这块物理内存,实现进程间通信,而且不需要数据的拷贝,所以速度最快. 二.内存映射mmap 1 前言:先介绍一 ...

  8. 进程间通信之共享内存SHM

    文章目录 1. system-v IPC简介 2. 函数ftok()函数介绍 3. 共享内存SHM介绍 4. 共享内存SHM相关接口函数 5. 共享内存SHM代码示例 1. system-v IPC简 ...

  9. 操作系统实验报告6:进程间通信—共享内存

    操作系统实验报告6 实验内容 实验内容:进程间通信-共享内存. (1).验证:编译运行课件 Lecture 08 例程代码: Linux 系统调用示例 reader-writer 问题:Algorit ...

  10. linux查看共享内存max,浅析Linux的共享内存与tmpfs文件系统

    浅析Linux的共享内存与tmpfs文件系统 前言 共享内存主要用于进程间通信,Linux有两种共享内存(Shared Memory)机制: (1)** System V shared memory( ...

最新文章

  1. 硕博士生参加学术会议重要吗?如何选择?注意什么?
  2. OpenCV 凸包Convex Hull
  3. 程序员修神之路--打通Docker镜像发布容器运行流程
  4. mysql函数match_Mysql全文搜索match…against的用法 | 学步园
  5. sql视图语句_SQL视图:Replace View语句的示例语法
  6. MySQL启动异常Starting MySQL.The server quit without .
  7. mysql 多点在 多边形,在MySQL中获取多点空间数据
  8. EventBus的基本使用步骤
  9. 怎样解决DEDE织梦友情链接字数限制与链接个数限制
  10. Java面试基础问题之(一)—— JDK和JRE区别
  11. 计算机地图制图的论文,计算机地图制图实习报告.doc
  12. vm16安装efi win7 方案
  13. 虾皮男装类目市场如何?哪些产品好卖?
  14. BIOS设置图解教程
  15. 峰值速率、系统容量、吞吐量、带宽之间的区别
  16. matlab设置非平坦结构元,基于多尺度多结构元的数学形态学边缘检测
  17. 学习R语言这几本电子书就够了!
  18. 正则将长数字转为英式写法(从后向前3个数字一个逗号)
  19. JavaScript检测邮箱 e-mail
  20. maven下手动导入ojdbc6-12.1.0.1-atlassian-hosted.jar

热门文章

  1. 福建农十林大的计算机专业怎么样,福建农林大学计算机与信息学院
  2. 分享商家为什么要做扫码点餐系统_微信小程序点餐系统有什么作用
  3. 同步钉钉组织架构和人员信息到本地Ldap
  4. 作文 深海机器人_关于机器人的作文7篇
  5. 无需编程基础,小白就能快速学会的数据可视化工具
  6. 51单片机之输入输出
  7. python中复杂的数据类型puple和list
  8. Java中求100的阶乘
  9. 洛谷网校的课程怎么样?
  10. 移动端图片鉴黄(可离线识别 200ms)