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

由于不同进程都可能向同一个空间读写数据,所以其需要一些同步机制来防止混乱,可以使用的机制有“信号量”“文件锁”等。 

共享内存有mmap和System V Shared Memory, 下面说的是后者。 

创建或打开共享内存: 

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

这与创建和打开消息队列的msgget非常类似,其同样用一个key_t类型的key来唯一标识被共享的内存。 size参数表示要创建的共享内存的大小,就像malloc函数一样。 shmflg参数和msgget函数的shmflg参数一样:其有两层含义,一是该参数可以取值IPC_CREATE,表示请求新建共享内存;也可以是 IPC_CREATE|IPC_EXCL的按位组合,表示请求新建共享内存但如果已经存在的话则报错。二是该参数表示权限控制,比如666表示全部可读写。那么如果该参数写成IPC_CREATE|IPC_EXCL|666则表示请求新建共享内存但如果已经存在的话则报错并且权限为666 

将共享内存attach到进程自己的虚拟内存空间: 

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

shmid参数: 

准备attach的共享内存id 

shmaddr参数: 

要将共享内存attach到的进程自己的虚拟空间地址,其需要和shmflg参数结合起来理解。 

)如果该参数传递一个空指针的话,则共享内存将被attach到由系统自动选择的第一块可能内存 

)如果该参数不为空: 

2.1)如果 shmflg & SHM_RND 不为0,那么共享内存将被attach到这个地址: 

(shmaddr -((uintptr_t)shmaddr %SHMLBA)).  

其中,SHM_RND标识表示取整对齐(round), SHMLBA是共享内存低段地址,也就是附加共享内存的边界地址。那么上面的计算公式意思是说:将shmaddr指定的地址移动到第边界地址的整数倍上。相反的,如果shmflg & SHM_RND为0,则直接使用shmaddr指定的地址。 

2.2)如果 (shmflg &SHM_RDONLY) 不为0,那么共享内存将变得只读(如果有读权限的话),相反的,(shmflg &SHM_RDONLY) 为0,则共享内存可读可写(如果有写权限的话) 

当attach成功后,共享内存在进程虚拟空间中的首地址将被返回,这时你就可以像操作普通内存一样来使用它了。 

attach的反向操作:将共享内存从进程的内存空间脱离 

int shmdt(const void *shmaddr); 

shmaddr参数就是原来attach上时的地址。 

共享内存所对应的数据结构(shmid_ds)和消息队列的数据结构(msqid_ds)非常的类似,相关操作也雷同: 

struct shmid_ds {
struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment (bytes) */
__kernel_time_t shm_atime; /* last attach time */
__kernel_time_t shm_dtime; /* last detach time */
__kernel_time_t shm_ctime; /* last change time */
__kernel_ipc_pid_t shm_cpid; /* pid of creator */
__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
unsigned short shm_nattch; /* no. of current attaches */
unsigned short shm_unused; /* compatibility */
void *shm_unused2; /* ditto - used by DIPC */
void *shm_unused3; /* unused */
}; int shmctl(int shmid, int cmd, struct shmid_ds *buf); 第一个参数表示要操作的共享内存的id cmd参数表示要执行的操作,与msgctl函数类似: )IPC_STAT获取消息队列属性信息,并将这些信息放置到第3个参数所设置的buffer中 )IPC_SET 根据buffer中的数据设置消息队列的一些属性,并非所有属性都可设置,其仅仅限于:ipc_perm.uid,ipc_perm.gid,ipc_perm.mode 这几种 )IPC_RMID 删除消息队列。 注:IPC_SET和IPC_RMID都会进行相应的权限检查,只有具备权限的进程才能执行相关操作

linux 进程学习笔记-共享内存的更多相关文章

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

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

  2. linux kernel学习笔记-5内存管理_转

    void * kmalloc(size_t size, gfp_t gfp_mask); kmalloc()第一个参数是要分配的块的大小,第一个参数为分配标志,用于控制kmalloc()的行为. km ...

  3. Linux 进程通信(共享内存区)

    共享内存是由内核出于在多个进程间交换信息的目的而留出的一块内存区(段). 如果段的权限设置恰当,每个要访问该段内存的进程都可以把它映像到自己的私有地址空间中. 如果一个进程更新了段中的数据,其他进程也 ...

  4. linux 进程通信之 共享内存

    共享内存是被多个进程共享的一部分物理内存.共享内存是进程间共享数据的一种最快的方法.一个进程向共享内存区域写入了数据,共享这个内存区域的全部进程就能够立马看到当中的内容. 关于共享内存使用的API k ...

  5. linux进程学习笔记

    学习了linux下的进程,觉得应该整理一下,忘得差不多了,顺便回顾一下. 学而时习之,不亦说乎~~ 进程笔记 ,什么是进程? The Single UNIX Specification, Versio ...

  6. linux 进程学习笔记-进程调度

    在分时系统中,系统将CPU时间划分成无数个时间片(quantum)分配给不同的进程,一个时间片只执行一个进程,并且不停地切换,以让用户感觉到各个进程是在“同时运行”,这中间所需要的策略和算法便是进程调 ...

  7. linux进程通信之共享内存

    共享内存同意两个或多个进程共享一给定的存储区,由于数据不须要来回复制,所以是最快的一种进程间通信机制.共享内存能够通过mmap()映射普通文件(特殊情况下还能够採用匿名映射)机制实现,也能够通过系统V ...

  8. linux 进程学习笔记-进程pipe管道

    所谓“进程间通信(IPC,inter-process communication)”,按照其目的讲就是让进程之间能够“共享数据”,“传输数据”,“事件通知”等,我所知道的一共有“管道” “信号” “消 ...

  9. linux 进程学习笔记-信号semaphore

    信号灯(信号量)不是进程通信手段,其是用于控制和协调在进程间通信过程中的共享资源访问,就如同互斥锁(两者的区别可以参考这里) 可以将简单地将信号灯想象成一个计数器,初始时计数器值为n(有n个资源可供使 ...

随机推荐

  1. 存储过程清理N天前数据

    CREATE OR REPLACE PROCEDURE APICALL_LOG_INTERFACE_CLEAN ( CLEANDAY IN Number --天数 ) AS v_cleanDay nu ...

  2. Android推断是否有sd卡

    推断手机上是否有SD卡存在.作为经常用法,写到工具类里,用时直接调用.代码例如以下: public static boolean hasSdcard(){ String state = Environ ...

  3. 智能手机的耗电特征及APP耗电量测试的两种方法

    文章陈述了手机发展趋势及耗电特性,集中讨论了时下最为关心的智能手机耗电问题,并介绍了测量手机软件耗电量的两种方法.此外还解释了为何运营商此前会提出收取微信的费用,心跳机制是什么. 美国著名手机公司Pa ...

  4. Android Calendar的学习与运用

    [java]mport java.text.DateFormat; import java.text.ParsePosition; import java.text.SimpleDateFormat; ...

  5. 下一代Apache Hadoop MapReduce框架的架构

    背景 随着集群规模和负载增加,MapReduce JobTracker在内存消耗,线程模型和扩展性/可靠性/性能方面暴露出了缺点,为此需要对它进行大整修. 需求 当我们对Hadoop MapReduc ...

  6. php解码“&#”编码的中文用函数html_entity_decode()

    遇到类似 ' 这种编码的字,我们可以用html_entity_decode()函数来解码. html_entity_decode() 函数把 HTML 实体转换为字符. 语法 html_entity_ ...

  7. 深入Asyncio(十一)优雅地开始与结束

    Startup and Shutdown Graceful 大部分基于asyncio的程序都是需要长期运行.基于网络的应用,处理这种应用的正确开启与关闭存在惊人的复杂性. 开启相对来说更简单点,常规做 ...

  8. 做一个合格的程序员之浅析Spring AOP源代码(十八) Spring AOP开发大作战源代码解析

    事实上上一篇文章价值非常小,也有反复造轮子的嫌疑,网上AOP的实例非常多,不胜枚举,事实上我要说的并非这个,我想要说的就是上一节中spring的配置文件: 我们这边并没实用到我们上几节分析的哪几个AO ...

  9. 转载 ----Android学习笔记 - 蓝牙篇 (Bluetooth)

      1.什么是蓝牙  Bluetooth是目前使用的最广泛的无线通讯协议之一  主要针对短距离设备通讯(10米)  常用于连接耳机.鼠标和移动通讯设备等 2.发现周围蓝牙设备  BluetoothAd ...

  10. 转载 ----MAC 上搭建lua

    MAC 上搭建lua   其实mac上搭建lua环境,google上大把资料,我只是整合一下,因为小弟搭建的时候确实碰到一些问题. 下载和安装lua:(转自这里) 1.  下载最新版的lua-5.2. ...