一、特点

  共享内存允许多个不同的进程可以访问同一块内存。相较于其他IPC形式,具有速度快,效率高的特点,共享内存的存在降低了在大规模数据处理过程中内存的消耗。

二、创建共享内存

  1、头文件

    #include <sys/ipc.h>

    #include <sys/shm.h>

    #include <sys/types.h>

  2、函数

    key_t ftok(const char *pathname, int proj_id);  创建IPC通讯时所必需的ID值。

      pathname:指定已经存在的文件名,一般是当前目录

      proj_id:子序列号,大小为1-255。

      返回值:ID值,大小是文件的索引节点号前加上子序列号,例如:pathname索引节点号为0x101010,proj_id为0x32,则ID为0x32101010。

    int shmget(key_t key, size_t size, int shmflg);   创建或打开一块共享内存

      key:标识符,每一个IPC对象与一个key相对应,大小为非0的整数

      size:指定共享内存的容量

      shmflg:权限标志,与open函数的mode参数类似。IPC_CREAT,如果key标识的内存不存在,则创建。IPC_EXCL,如果key标识的内存存在,则报错,errno为EEXIST。

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

    void *shmat(int shmid, const void *shmaddr, int shmflg);  把共享内存区对象映射到调用进程的地址空间

      shmid:共享内存的标识符。

      shmaddr:指定共享内存连接到当前进程中的地址位置,可以为NULL,表示让系统选择共享内存的地址

      shmflg:权限标志,SHM_RND 读写,SHM_RDONLY 只读。

      返回值:成功返回共享内存的首地址,失败返回-1。

      注:fork后子进程继承已连接的共享内存地址。exec后该子进程与已连接的共享内存地址自动脱离(detach)。进程结束后,已连接的共享内存地址会自动脱离(detach)

    int shmdt(const void *shmaddr);  取消进程与共享内存的关联关系。

      shmaddr:共享内存的首地址。

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

      注:shmdt不会删除共享内存,只是将当前进程与共享内存分离。

    int shmctl(int shmid, int cmd, struct shmid_ds *buf);   操纵共享内存

      shmid:共享内存标识符。

      cmd:IPC_STAT,得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中。IPC_SET,改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内。IPC_RMID,标识将要删除这片共享内存。

      buf:共享内存的管理结构体

  1. struct shmid_ds {
  2. struct ipc_perm shm_perm; /* Ownership and permissions */
  3. size_t shm_segsz; /* Size of segment (bytes) */
  4. time_t shm_atime; /* Last attach time */
  5. time_t shm_dtime; /* Last detach time */
  6. time_t shm_ctime; /* Last change time */
  7. pid_t shm_cpid; /* PID of creator */
  8. pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
  9. shmatt_t shm_nattch; /* No. of current attaches */
  10. ...
  11. };
  12.  
  13. struct ipc_perm {
  14. key_t __key; /* Key supplied to shmget(2) */
  15. uid_t uid; /* Effective UID of owner */
  16. gid_t gid; /* Effective GID of owner */
  17. uid_t cuid; /* Effective UID of creator */
  18. gid_t cgid; /* Effective GID of creator */
  19. unsigned short mode; /* Permissions + SHM_DEST and
  20. SHM_LOCKED flags */
  21. unsigned short __seq; /* Sequence number */
  22. };

      注:IPC_RMID仅是将共享内存标记为删除。如果共享内存仅有当前进程连接,则直接删除。如果还有其他进程,则会将当前进程从连接中删除,并且将共享内存标识符改为0,表明其为PRIVATE状态,阻止其他进程再连接共享内存,等待其他进程断开连接后删除共享内存。

查看共享内存状态:ipcs指令

[笔记]共享内存(shm)的更多相关文章

  1. Centos下10000次循环测试php对Redis和共享内存(shm)读写效率

    redis和memcache还有共享内存都是读取内存的数据,为了测试一下到底效率谁更胜一筹,我在我的Centos虚拟机下做了一次公平的测试. 测试参数 环境:Centos (配置忽略).语言:PHP. ...

  2. C扩展 从共享内存shm到memcache外部内存

    引言 - ipc - shm 共享内存 本文会通过案例了解ipc 的共享内存机制使用, 后面会讲解C 如何使用外部内存服务memcached. 好先开始了解 linux 共享内存机制. 推荐先参看下面 ...

  3. ubuntu linux c学习笔记----共享内存(shmget,shmat,shmdt,shmctl)

    shmget int shmget(key_t key, size_t size, int flag); key: 标识符的规则 size:共享存储段的字节数 flag:读写的权限 返回值:成功返回共 ...

  4. linux 进程学习笔记-共享内存

    如果能划定一块物理内存,让多个进程都能将该内存映射到其自身虚拟内存空间的话,那么进程可以通过向这块内存空间读写数据而达到通信的目的.另外,和消息队列不同的是,共享的内存在用户空间而不是核空间,那么就不 ...

  5. 共享内存shm*(生产者和消费者)

    //heads.h #ifndef HEAD_H #define HEAD_H #include <iostream> #include <sys/shm.h> //share ...

  6. vector存入共享内存(了解)

    昨天在上篇blog里描写了如何把STL容器放到共享内存里去,不过由于好久不写blog,发觉词汇组织能力差了很多,不少想写的东西写的很零散,今天刚好翻看自己的书签,看到一篇挺老的文章,不过从共享内存到S ...

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

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

  8. C 共享内存封装

    引言 - 背景 2016 年写过一篇关于 linux 共享内存 shm api 扫盲文. C扩展 从共享内存shm到memcache外部内存 比较简单. 没有深入分析(能力有限, 也深入分析不了). ...

  9. Linux下IPC之共享内存的使用方法

    基本参考 <Unix环境高级编程>第14.9节共享内存来学习. 参考blog:https://blog.csdn.net/weixin_45794138/article/details/1 ...

随机推荐

  1. 进阶Java编程(3)线程的同步与死锁

    线程的同步与死锁 1,同步问题引出 在多线程的处理之中,可以利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象,对于当多个线程访问统一资源的时候如果处理不当就会产生数据的错误 ...

  2. Spingboot+Mybatis+Oracle项目配置

    配置过程参考: 项目创建:http://how2j.cn/k/springboot/springboot-eclipse/1640.html 集成Mybatis使用Oracle:https://www ...

  3. 题解 CF670C 【Cinema】

    题目链接: https://www.luogu.org/problemnew/show/CF670C 思路: step-1: 语言的数据范围是10^9,所以我们采取用map离散化,这样就能方便且不ML ...

  4. O064、NFS Volume Provider(Part III)

    参考https://www.cnblogs.com/CloudMan6/p/5702199.html   今天我们将前一小节中创建的 nfs-vol-xx attach 到Instance c1 上, ...

  5. opencv+ linux + cmake 生成 opencv静态库

    您可以省去如下步骤,直接下载我编译好的: http://download.csdn.net/detail/u011258240/9710331 一.编译opencv2.4  不带contrib 1. ...

  6. JavaScript的常用浏览器设置

    用什么浏览器?如果您不告诉我您使用的浏览器,我将告诉您有关JavaScript的常用浏览器设置.~火狐在菜单栏中选择工具->选项->内容以查看启用javascript的选项.Interne ...

  7. go语言入门(5)工程管理

    在工程中不会简单到只有一个源代码文件,且源文件之间会有相互的依赖关系,早期Go语言使用makefile作为工程管理的临时方案,后来的Go命令行工具的革命性之处在于彻底消除了工程文件的概念,完全用目录结 ...

  8. python连接postgres方法

    Python使用PyGreSQL操作PostgreSQL: import pg def operate_postgre_tbl_product(): try: #db = pg.connect(dbn ...

  9. mysql使用存储过程,批量生成测试数据

    1.存储过程代码 delimiter $$DROP PROCEDURE IF EXISTS create_service_data$$create procedure create_service_d ...

  10. linux命令详解——sed

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法 sed命令行格式为:          se ...