linux 进程间通信(IPC)包括3种机制:消息队列、信号量、共享内存。消息队列和信号量均是内核空间的系统对象,经由它们

的数据需要在内核和用户空间进行额外的数据拷贝;而共享内存和访问它的所有应用程序均同处于用户空间,应用进程可以通过地址

映射的方式直接读写内存,从而获得非常高的通信效率。在GNU/Linux中所有的进程都有唯一的虚拟地址空间,而共享内存应用编程

接口API允许一个进程使用公共内存区段。 如果使用消息队列进行通信,那么一个进程要向队列中写入消息,这要引起从用户地址空

间向内核地址空间的一次复制,同样一个进程进行消息读取时也要进行一次复制,而共享内存的优点是完全省去了这些操作。两个不

同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数

据的更新,反之亦然,因此通过共享内存映射到进程的虚拟地址空间,进程对其可以直接访问,避免了数据的复制过程。由于多个进程

共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量

共享内存区的相关操作:

使用共享内存的流程:
   1.进程必须首先分配它。
   2.随后需要访问这个共享内存块的每一个进程都必须将这个共享内存绑定到自己的地址空间中。
   3.当完成通信之后,所有进程都将脱离共享内存,并且由一个进程释放该共享内存块。

#include <sys/ipc.h>
#include <sys/shm.h>
/*
创建一个新的内存共享区或者访问一个已经存在的共享内存区
返回共享内存区标识符
*/
int shmget(key_t key, size_t size, int shmflg);
/*
创建或打开一个共享内存区后,调用shmat把它连接到调用进程的地址空间
*/
void *shmat(int shmid, const void *shmaddr,int shmflg);
/*
当一个进程完成某个共享内存区的使用时,调用shmdt断开这个内存区
*/
int shmdt(const void *shmaddr);
/*
对内存区进行多种操作
cmd取值:
IPC_RMID:从系统中删除由shmid标识的共享内存区并拆除它
IPC_SET:给指定的共享内存区设置其shmid_ds结果成员
IPC_STAT:通过buff参数向调用者返回所指定共享内存区当前的shmid_ds结构
*/
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

#include<sys/types>

#include<sys/ipc.h>

#include<sys/shm.h>

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

             参数:
                     key:ftok返回值或者IPC_PRIVATE
                     size:共享内存区大小( 字节为单位,if访问一个已经存在的,那么就是0 )
                     oflag:权限的组合

shmget()函数用于创建一个新的共享内存段,或者访问一个现有的共享内存段,它与消息队列以及信号集合对应的函数十分相似.如

果shmflg只为IPC_CREAT,shmget()或者将返回新创建的内存段标识符,或者返回早已存在于内核中的具有的相同关键字值(key)

的内存段的标识符;如果其同时为IPC_CREAT和IPC_EXCL,则如果该内存段不存在就创建一个新的内存段,如果早已存在,则此时

调用失败,并将返回-1.

#include<sys/types>

#include<sys/ipc.h>

#include<sys/shm.h>

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

int shmdt(const void *shmaddr);

函数shmat()用来获取共享内存的地址,获取成功后,就可以像使用普通内存一样对其进行读写操作。

#include<sys/types>

#include<sys/ipc.h>

#include<sys/shm.h>

int shmdt(const void *shmaddr);

当某一个进程不再需要一个共享内存段时,它必须调用这个函数来断开与该内存段的连接

#include<sys/types>

#include<sys/ipc.h>

#include<sys/shm.h>

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

共享内存控制函数,它的使用类似ioctl()的方式对共享内存进行操作:向共享内存的句柄发送命令,来完成某种命令

对于每个共享的内存区,内核维护如下的信息结构,定义在<sys/shm.h>头文件中。

 1 struct shmid_ds {
2   struct ipc_perm shm_perm;     /* operation perms */
3   int 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   unsigned short shm_cpid;      /* pid of creator */
8   unsigned short shm_lpid;      /* pid of last operator */
9   short shm_nattch;          /* no. of current attaches */
10   /* the following are private */
11   unsigned short shm_npages;      /* size of segment (pages) */
12   unsigned long *shm_pages;       /* array of ptrs to frames -> SHMMAX */
13   struct vm_area_struct *attaches;   /* descriptors for attaches */
14 };

这里有点要注意,当我们调用shmdt()来删除共享内存段时,只是断开该进程与这个内存段的连接,而此时内核不一定就删除内存段,

结合上述,在成功完成了断开连接操作后,相关的shmid_ds结构的shm_nattch成员的值将减去1,如果这个值减到0,则内核将真正

删除该内存段。

linux编程之共享内存的更多相关文章

  1. Linux信号量同步共享内存实验.

    Linux信号量同步共享内存实验. Linux信号量同步共享内存实验. 简述 程序流程 信号量和共享内存的系统函数 信号量系统函数及接口 共享内存系统函数及接口 写程序 读程序 简述 本文主要内容是自 ...

  2. Linux环境进程间通信: 共享内存

    Linux环境进程间通信: 共享内存 第一部分 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进 ...

  3. Linux IPC之共享内存C 事例

    Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报  分类: Linux(3)  读书札记(3)  版权 ...

  4. Linux进程间通信—使用共享内存

    Linux进程间通信-使用共享内存 转自: https://blog.csdn.net/ljianhui/article/details/10253345 下面将讲解进程间通信的另一种方式,使用共享内 ...

  5. Linux环境编程之共享内存区(一):共享内存区简单介绍

    共享内存区是可用IPC形式中最快的.一旦内存区映射到共享它的进程的地址空间,进程间数据的传递就不再涉及内核.然而往该共享内存区存放信息或从中取走信息的进程间通常须要某种形式的同步.不再涉及内核是指:进 ...

  6. linux网络编程之共享内存介绍

    今天是个好日子,洋人之节乃全球同庆,圣诞一来感觉就要过年了,不过今晚心情有点打折扣,给心爱的人打电话没有打通,本想在平安夜送上快乐的祝福给她,糟糕的心情让自己好像泄了气的皮球一样,无精打彩,心情灰暗, ...

  7. Linux IPC POSIX 共享内存

    模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...

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

    一,共享内存  内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存.  映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点 ...

  9. Linux进程间通信——使用共享内存

    一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式.不同进程之间共享的内存通常安排为同一段物理内存. ...

随机推荐

  1. Activiti5工作流笔记二

    流程变量 import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.activiti ...

  2. 使用mac电脑,对Github客户端的简单操作1----开源项目

    工作之余自己也会一写一些小的程序项目,由于一直没时间“折腾”开源,之前写博客都是直接粘代码片段,今天看别人写技术博客大都会放出项目Github地址,突然感觉自己有点点out and low,作为一个励 ...

  3. HDU 3879 Base Station(最大权闭合子图)

    将第i个用户和他需要的基站连边,转化成求二分图的最大权闭合子图. 答案=正权点之和-最小割. # include <cstdio> # include <cstring> # ...

  4. BZOJ 1297 迷路(矩阵快速幂)

    很容易想到记忆化搜索的算法. 令dp[n][T]为到达n点时时间为T的路径条数.则dp[n][T]=sigma(dp[i][T-G[i][n]]); 但是空间复杂度为O(n*T),时间复杂度O(n*n ...

  5. HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值)

    HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值) 点我挑战题目 题意分析 从题目中可以看出是大数据的输入,和大量询问.基本操作有: 1.Q(i,j)代表求区间max(a ...

  6. [学习笔记]FFT——快速傅里叶变换

    大力推荐博客: 傅里叶变换(FFT)学习笔记 一.多项式乘法: 我们要明白的是: FFT利用分治,处理多项式乘法,达到O(nlogn)的复杂度.(虽然常数大) FFT=DFT+IDFT DFT: 本质 ...

  7. 分享一个JQuery弹出层插件

    JQuery插件TipsWindown 1.1 一个基于jQuery的弹出层.支持拖拽,支持内容为文字,图片,URL等!至于兼容性.在IE6下,弹出对像无法绝对固定.其他应该没啥大问题: 最新更新:( ...

  8. Linux上读取文件

    Linux上读取文件的方法: #!/bin/bash # This is a script for test exec CONFIG_FILE=$ #该脚本传一个文件名为参数 FILE_NO= ech ...

  9. ACE中TCP通信

    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/07/585095.html 概述: 传输控制协议TCP(Transmission Contro ...

  10. Android LocalBroadcastManager解析

    阿里巴巴Android开发手册[强制]避免使用隐式 Intent 广播敏感信息,信息可能被其他注册了对应BroadcastReceiver 的 App 接收.说明:通过 Context#sendBro ...