一.概述                                                   

1.共享内存允许多个进程共享物理内存的同一块内存区。

2.与管道和消息队列不同,共享内存在用户内存空间,不需要内核介入。降低了内核和用户缓冲区的数据复制开销。所以这种IPC速度比较快。

3.多个进程共享内存时需要其他同步机制来控制临界区,如上一篇的信号量

二.函数接口                                            

1.创建或打开共享内存

 #include <sys/shm.h>

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

key和shmflg同消息队列和信号量一样,这里不再叙述。

size:需要分配内存的大小

2.使用共享内存

 #include <sys/shm.h>

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

shmid:shmget()返回的值

shmaddr:把刚刚创建的内存指向该指针。如果是NULL,内核会自动选择。

shmflg:如果shmaddr不为NULL,shmflg控制shmaddr如果指向内存。如内存只读,计算内存地址倍数等,可以查看man手册。

3.分离共享内存

 #include <sys/shm.h>

 int shmdt(const void *shmaddr);

shmaddr是该进程指向共享内存的指针。把该共享内存从该进程分离,即该共享内存和该进程没有联系了。分离后,共存内存依然存在。

4.控制共享内存

 #include <sys/shm.h>

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

cmd和消息队列一样,IPC_RMID是删除共享内存。

三.简单例子                                            

我们写2个小程序,第一个创建和拷贝数据到共享内存,第二个读取共享内存数据并删除共享内存。

1.创建和拷贝

 /**
  * @file shm1.c
  */

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/shm.h>

 #define SHARE_MEM_BUF_SIZE 1024

 void err_exit(const char *err_msg)
 {
     printf("error:%s\n", err_msg);
     exit();
 }

 int main(void)
 {
     int shm_id;
     void *share_mem;
     ";

     shm_id = shmget(IPC_PRIVATE, SHARE_MEM_BUF_SIZE,  | IPC_CREAT);
     )
         err_exit("shmget()");

     printf("shm_id:%d\n", shm_id);

     /* 把创建的共享内存指向该程序的一个指针 */
     share_mem = shmat(shm_id, NULL, );
     )
         err_exit("shmat()");

     /* 拷贝数据到共享内存 */
     memcpy((char *)share_mem, text, strlen(text));

     /* 分离共享内存 */
     )
         err_exit("shmdt()");

     ;
 }

2.读取并删除

 /**
  * @file shm2.c
  */

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/shm.h>

 #define SHARE_MEM_BUF_SIZE 1024

 void err_exit(const char *err_msg)
 {
     printf("error:%s\n", err_msg);
     exit();
 }

 int main(int argc, const char *argv[])
 {
     )
     {
         printf(]);
         exit();
     }

     void *share_mem;
     ]);

     /* 把创建的共享内存指向该程序的一个指针 */
     share_mem = shmat(shm_id, NULL, );
     )
         err_exit("shmat()");

     /* 读取数据 */
     printf("read data:%s\n", (char *)share_mem);

     /* 分离共享内存 */
     )
         err_exit("shmdt()");

     /* 删除共享内存 */
     ) == -)
         err_exit("shmctl()");

     ;
 }

四.实验                                                   

1.shm1.c用IPC_PRIVATE方式让内核自动创建一个key,并分配1024字节内存。第36行把"123456"拷贝到共享内存。

2.shm2.c从命令行来指定要使用的共享内存,第35行读取数据,第42行删除数据。

3.运行shm1后,可以得到共享内存的shmid,可以用ipcs -m | grep 'xxx'查看:

可以看到我们分配的1024字节内存。

4.运行shm2接收shmid=50954258的数据并删除共享内存,再用ipcs -m | grep 'xxx'查看:

可以看到读取了"123456"数据,用ipcs查看时,已被删除。

System V IPC(3)-共享内存的更多相关文章

  1. System V IPC 之共享内存

    IPC 是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行系列操作的一组机制: 通过信号量与其他进程进行同步 向其他进程发送消息或者从其他进程接收消息 ...

  2. 五十、进程间通信——System V IPC 之共享内存

    50.1 共享内存 50.1.1 共享内存的概念 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到自己的虚拟内存空间.所有用户空间的进程若要操作共享内存,都要将其映射到自己 ...

  3. System V IPC 之信号量

    本文继<System V IPC 之共享内存>之后接着介绍 System V IPC 的信号量编程.在开始正式的内容前让我们先概要的了解一下 Linux 中信号量的分类. 信号量的分类 在 ...

  4. 进程间通信IPC之--共享内存

    每个进程各自有不同的用户地址空间,任何一个进 程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲 ...

  5. 第3章 System V IPC

    3.1 概述 System V IPC 包含:System V消息队列.System V信号量.System V共享内存. 3.2 key_t 键和 ftok函数 这三种类型的System V IPC ...

  6. 《Unix网络编程》卷2 读书笔记 第3章- System V IPC

    1. 概述 三种类型的System V IPC:System V 消息队列.System V 信号量.System V 共享内存区 System V IPC在访问它们的函数和内核为它们维护的信息上共享 ...

  7. 从并发处理谈PHP进程间通信(二)System V IPC

    .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...

  8. System V IPC 之消息队列

    消息队列和共享内存.信号量一样,同属 System V IPC 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型 ...

  9. 四十九、进程间通信——System V IPC 之消息队列

    49.1 System V IPC 介绍 49.1.1 System V IPC 概述 UNIX 系统存在信号.管道和命名管道等基本进程间通讯机制 System V 引入了三种高级进程间通信机制 消息 ...

随机推荐

  1. 钉钉客户端JS-API权限签名算法.NET版

    前段时间写了一篇博文<钉钉如何进行PC端开发>,在里面并未解决本地生成签名的问题,需要到官网进行生成,由于钉钉门票等认证信息会超期,因此,必须能本地用代码自动更新相关参数信息,来换取签名. ...

  2. Could not load file or assembly 'Microsoft.SqlServer.Management.Sdk.Sfc, Version=11.0.0.0 系统找不到指定的文件。

    环境: web服务器: ip:192.168.1.32 ,安装有 Visual Studio Premium 2013 操作系统: Microsoft  Server 2008 r2+sp1 数据库服 ...

  3. SharePoint Online 创建门户网站系列之定制栏目

    前 言 SharePoint Online自带的库就带有二级页面和详细页面,也就是Allitems页面和DispForm页面,但是实在不够美观,尤其对于门户网站这一企业门面来说,更是无法接受. 下面, ...

  4. sharepoint 弹出窗口

    function openAnswerQandADialog(aUrl,aTitle) { var options = { url: aUrl, width: 1024, height: 768, t ...

  5. SharePoint回环检查(Loopback Check)相关问题

    Loopback Check(回环检查)本来不是一个SharePoint问题,是Windows Server为了增强自身安全性在Server 2003 SP1后引入的一个功能, 在近几个月中导致了一系 ...

  6. bootstrap的一些资源

    http://www.cnblogs.com/landeanfen/p/5461849.html 总结了时间,加载,自动增加图片选择,等bootstap控件 http://www.cnblogs.co ...

  7. spring.net (2)环境搭建 对(1)例子的解释和扩充

    在上文中的例子实现了spring.net 控制反转的简单例子: 但是不免其中会有一些疑问. 例子中的配置文件是什么意思: app.config的配置规则可以参考web.config的配置详情 < ...

  8. 【读书笔记】iOS网络-底层网络

    在iOS上,有一个库叫做Core Foundation networking或CFNetwork,它是对原始Socket的轻量级封装,不过它很快对于大多数常见场景来说变得非常笨重了.最后,添加了另一层 ...

  9. Swift 二维码扫描 简单实现

    3.30看视频  学到了二维码简单的实现 还有一些动画的实现  今天就先记录一下二维码扫描的简单实现  不太好记手写一遍 学习的基础在于模仿嘛 创建一个实现二维码扫描的步骤 1.首先是懒加载创建 会话 ...

  10. AOP的实现机制

    1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较. 类别 ...