ipcs / ipcrm 介绍:
ipcs 可以查看消息队列、共享内存、信号量的使用情况,使用 ipcrm 可以进行删除操作。

一、共享内存原理
进程可同时访问同一块内存,对进程没有要求。<sys/shm.h>
共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理
内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访
问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了
数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供
同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。
二、参数介绍
1.shmget():创建或者获取共享内存
成功返回共享内存的 ID, 失败返回-1。
int shmget(key_t key, size_t size, int shmflg);
key:共享内存段唯一标识符,不同进程使用相同的key值可以获取到同一个共享内存。
size:共享内存的大小,必须是整数,如果是获取共享内存段,可填0。
shmflg: 用于控制函数的行为。
IPC_CREAR:如果key不存在,则创建新段。
IPC_EXCL: 与IPC_CREAT结合使用,如果已存在,会报错。
权限控制:需要指定权限0600。
2.shmat():将申请的共享内存的物理内存映射到当前进程的虚拟地址空间上。
成功返回共享内存首地址,失败返回NULL。
将一个已存在的共享内存段附加一个内存块到进程的地址空间中,一旦附加成功,进程就可以像访问普通内存一样访问共享区域。
void *shmat(int shmid, const void *_Nullable shmaddr, int shmflg);
shmid:共享内存段id号,由shmget返回获取。
shmaddr:指定共享内存要附加到地址空间的哪个位置。
NULL:一般让内核自动选择映射的虚拟地址空间。
非NULL:如果shmget没有设置标志,会定位一个精确位置,如果该地址不可用,函数调用失败。
shmflg:标志位,决定函数附加功能。
0:默认权限,根据创建时的权限进行操作。
SHM_RDONLY: 只读访问共享内存,如果写操作,会段错误。
SHM_EXEC: 允许在共享内存段上执行代码。
3.shmdt():断开当前进程的shmaddr指向的共享内存映射。
成功返回0,失败返回-1。
断开附加内存块,不允许内存块上的内容影响共享内存。
int shmdt(const void *shmaddr);
shmaddr: 附加的内存块的地址。
4.shmctl():控制共享内存。
成功返回0,失败返回-1。
int shmctl(int shmid, int op, struct shmid_ds *buf);
op: IPC_RMID。
三、代码练习
示例代码 1:进程 a 向共享内存中写入数据,进程 b 从共享内存中读取数据并显示。
a.c 的代码:
b.c的代码:
运行结果:
示例代码 2:进程 a 从键盘循环获取数据并拷贝到共享内存中,进程 b 从共享内存中获
取并打印数据。要求进程 a 输入一次,进程 b 输出一次,进程 a 不输入,进程 b 也不输出。
由于共享内存并未提供同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。
下面代码将使用有名管道来同步。
a.c的代码:
b.c的代码:
运行结果: