进程间通讯有四种方式:信号量、管道、消息队列、共享内存
我们之前已着重介绍过信号量、管道。
现着重介绍一下共享内存。
共享内存
共享内存是最高效的IPC机制,因为它不涉及进程之间任何的数据传输。这种高效率带来的问题是,我们必须用其他辅助手段来同步进程对共享内存的访问,否则就会产生竞态条件。因此,共享内存通过和其他进程间通信方式一起使用。
Linux共享内存的API都定义在sys/shm.h头文件中,包括4个系统调用函数:shmget、shmat、shmdt和shmctl
shmget
shmget系统调用创建一段新的共享内存,或者获取一段已经存在的共享内存。请定义如下:
#include<sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
和semget系统调用一样,key参数是一个键值,用来表示一段全局唯一的共享内存。size参数指定共享内存的大小,单位是字节。如果是创建新的共享内存,则size值必须被指定。如果是获取已经存在的共享内存,则可以把size设置为0。
shmflg参数的使用和含义与semget系统调用的sem_flags参数相同。不过shmget支持两个额外的标志——SHM_HUGETLB和SHM_NORESERVE。它们的含义如下:
SHM_HUGETLB,类似于mmap的MAP_NORESERVE标志,系统将使用“大页面”来共享内存分配空间。
SHM_NORESERVE,类似于mmap的MAP_NORESERVE标志,不为共享内存保留交换分区(swap空间)。这样,当物理内存不足的时候,对该共享内存执行写操作将触发SIGSEGV信号。
这里sem_flags参数:它低端的9个比特是该信号量的权限,其格式和含义都与系统调用open的mode参数相同。此外,它还可以和IPC_CREAT标志做按位“或”运算以创建新的信号量集。此时即使信号量已经存在,semget也不会产生错误。我们还可以联合使用IPC_CREAT和IPC_EXCL标志来确保创建一组新的、唯一的信号量集。在这种情况下,如果信号量集已经存在,则semget返回错误并设置errno为EEXIST。这种创建信号量的行为与用O_CREA