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. jQuery返回顶部代码

    页面较长时,使用返回顶部按钮比较方便,在电商中必备操作.下面自己制作一个js文件,totop.js,把它直接引用到需要的网页中即可. $(function () { $("body" ...

  2. RT-thread内核之线程调度器

    一.前言 RT-Thread中提供的线程调度器是基于全抢占式优先级的调度,在系统中除了中断处理函数.调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的,包括线程调度器自 ...

  3. 在a标签的href用户#name 的可以实现页面 上下跳转

  4. BZOJ 1015 星球大战(并查集)

    正着不好搞,考虑倒着搞.倒着搞就是一个并查集. # include <cstdio> # include <cstring> # include <cstdlib> ...

  5. Python单例模式的四种方法

    在这之前,先了解super()和__new__()方法 super()方法: 返回一个父类或兄弟类类型的代理对象,让你能够调用一些从继承过来的方法. 它有两个典型作用: a. 在单继承的类层次结构中, ...

  6. monitor_guiagent

    monitor_guiagent monitor_guiagent.sh #!/usr/bin/env bash #filename : monitor_guiagent.sh #Usage: /us ...

  7. BZOJ4898 & BZOJ5367 & 洛谷3778:[APIO2017]商旅——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4898 https://www.lydsy.com/JudgeOnline/problem.php? ...

  8. BZOJ2761 不重复的数字 【treap】

    2761: [JLOI2011]不重复数字 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 5517  Solved: 2087 [Submit][S ...

  9. js空对象判断 isPlainObject

    //有缺陷,JSON.stringify(obj)中,如果obj本来是空的,又继承了一个非空的对象那么结果也会是“{}” 1. JSON.stringify(obj) == '{}' 2. Objec ...

  10. Ubuntu安装CUDA9.0 + cuDNN

    本篇文章是基于安装CUDA 9.0的经验写,CUDA9.0目前支持Ubuntu16.04和Ubuntu17.04两个版本,如下图所示(最下面的安装方式我们选择第一个,即runfile方式): 下载链接 ...