Linux下的进程通信方式之System_V共享内存
Linux下的通信方式之 System_V 共享内存
共享内存是 IPC 三种通信方式中,性能最好的一种。其允许两个或以上的进程通过访问一块公共的内存空间(通常称为段)来达到通信的方式。
由于一个共享内存段会成为一个进程的用户空间内存的一部分,所以这种通信方式是无需内核参与的。这也是共享内存这种通信方式和消息队列、信号量的巨大不同。后两者是需要将数据从用户空间复制到内核空间的。
另一方面,共享内存这种 IPC机制不由内核控制意味着通常需要通过某些同步方法使得进程不会出现同时访问共享内存的情况(如两个进程同时执行更新操作或者一个进程在从共享内存中获取数据的同时另一个进程正在更新这些数据)。System V信号量天生就是用来完成这种同步的一种方法。当然,还可以使用其他方法,如 POSIX信号量和文件锁。(没有同步机制是共享内存的一个缺陷)
概述
为使用一个共享内存段通常需要执行下面的步骤:
● 调用 shmget()创建一个新共享内存段或取得一个既有共享内存段的标识符(即由其他进程创建的共享内存段)。这个调用将返回后续调用中需要用到的共享内存标识符。
● 使用 shmat()来附上共享内存段,即使该段成为调用进程的虚拟内存的一部分。
● 此刻在程序中可以像对待其他可用内存那样对待这个共享内存段。为引用这块共享内存,程序需要使用由 shmat()调用返回的 addr值,它是一个指向进程的虚拟地址空间中该共享内存段的起点的指针。
● 调用 shmdt()来分离共享内存段。在这个调用之后,进程就无法再引用这块共享内存了。这一步是可选的,并且在进程终止时会自动完成这一步。
● 调用 shmctl()来删除共享内存段。只有当当前所有附加内存段的进程都与之分离之后内存段才会被销毁。只有一个进程需要执行这一步。
相关函数
shmget()
1 |
|
作用:创建新的共享内存或引用一个现有的共享内存。当创建一个新的共享内存时,初始化shmid_ds结构下列成员。
ipc_perm结构。其中mode按shmflg中的相应权限位设置
shm_lpid、shm_nattach、shm_atime和shm_dtime都设置为0.
shm_ctime设置为当前时间
shm_segsz设置为请求的size
如果创建一个新的共享内存段(通常在服务器进程中),则必须指定其size。如果正在引用一个现存的段(一个客户进程),则将size指定为0。当创建一个新共享内存时,段内的内容初始化为0.
shmat()
1 |
|
作用:第一次创建共享内存时,它不能被任何进程访问。要想启用该共享内存的访问,必须将其连接到一个进程的地址空间中。
shmdt()
1 |
|
作用:将共享内存从当前进程中分离(并不是删除)。 如果调用成功,shmdt将使相关shmid_ds结构中的shm_nattch计数器值减1。如果想要删除这个共享内存则需要使用函数 shmctl()
shmctl()
1 |
|