1. 苏葳的备忘录首页
  2. 编程

在UNIX下共享内存中定义数据结构及IPC的清理。

unix 共享内存 ipc顾名思义,共享内存让一段内存可供多个进程访问。用特殊的系统调用(即对UNIX内核的请求)分配和释放内存并设置权限;通过一般的读写操作读写内存段中的数据。共享内存并不是从某一进程拥有的内存中划分出来的;进程的内存总是私有的。共享内存是从系统的空闲内存池中分配的,希望访问它的每个进程连接它。这个连接过程称为映射,它给共享内存段分配每个进程的地址空间中的本地地址。

#include <sys/shm.h>
struct nano{
    char aa[4];
} ks[3];
int shmid;
struct nano *pmat;
shmid = shmget(MEMKEY, 10*sizeof(struct nano), 0666|IPC_CREAT|IPC_EXCL);
pmat = (struct nano *)shmat(shmid, 0, 0);

如此,便可获得一块映射后地址为pmat的共享内存,此块内存以结构nano的形式操作。之前一直困惑线性数据结构如何往复杂结构转换,现在看来,(struct nano *)式的强制类型转换就OK了。

但是多维数组和指针间的映射仍有些迷糊,多年未用C,很多细节记不清楚。所以才用nano式的结构数组来模拟了二维数组。

将共享内存映射入本进程空间之后,可如正常操作结构数组形式操作数据,如pmat[2].aa等。

在子进程退出后,此段共享数据仍保存,一般情况下,子进程创建时,shmget会自动增加此共享内存引用计数,而退出时,会自动减少一引用计数,当引用计数为0时,共享内存自动删除。但手册推荐用shmdt强制减少引用计数。当然,由于服务多以死循环(while (1))的形式运行,所以在服务的stop批处理中除了kill掉服务进程外,用ipcrm 删除掉共享内存也是必不可少的。一般服务的stop命令 杀进程,清ipc 清临时文件,可以有一通用模板来做,正如之前博客记录的批处理一样。该批处理是查找本服务用户名所属的进程,共享内存,信号量,消息队列等等,一并清掉。所以若以此种方式stop,则最好为此服务程序单独创建一用户,以防误杀。

ipcs可查看系统中运行的IPC,可用

ipcrm [ -m SharedMemoryID ] [ -M SharedMemoryKey ] [ -q MessageID ] [ -Q
MessageKey ] [ -s SemaphoreID ] [ -S SemaphoreKey ]

来清除相应IPC。

由于涉及并发操作,通常共享内存会与信号量合用,留待进一步研究。

原创文章,作者:苏葳,如需转载,请注明出处:https://www.swmemo.com/310.html

发表评论

邮箱地址不会被公开。 必填项已用*标注