shmctl 实现对共享 内存区域的控制操作。 这里我们不对这些系统调用作具体的介绍, 读者可参考相应的手册页 面,后面的范例中将给出它们的调用方法。 注:shmget 的内部实现包含了许多重要的系统 V 共享内存机制;shmat 在把共享内存区域 映射到进程空间时,并不真正改变进程的页表。当进程第一次访问内存映射区域访问时,会 因为没有物理页表的分配而导致一个缺页异常, 然后内核再根据相应的存储管理机制为共享 内存映射区域分配相应的页表。 回页首 3、系统 V 共享内存限制 在/proc/sys/kernel/目录下,记录着系统 V 共享内存的一下限制,如一个共享内存区的最大 字节数 shmmax,系统范围内最大共享内存区标识符数 shmmni 等,可以手工对其调整,但 不推荐这样做。 在[2]中,给出了这些限制的测试方法,不再赘述。 回页首 4、系统 V 共享内存范例 本部分将给出系统 V 共享内存 API 的使用方法, 并对比分析系统 V 共享内存机制与 mmap() 映射普通文件实现共享内存之间的差异,首先给出两个进程通过系统 V 共享内存通信的范 例: /***** testwrite.c *******/ #include #include #include #include typedef struct{ char name[4]; int age; } people; main(int argc, char** argv) { int shm_id,i; key_t key; char temp; people *p_map; char* name = "/dev/shm/myshm2"; key = ftok(name,0); if(key==-1) perror("ftok error"); shm_id=shmget(key,4096,IPC_CREAT); if(shm_id==-1) { perror("shmget error"); return; } p_map=(people*)shmat(shm_id,NULL,0); temp='a'; for(i = 0;i<10;i++) { temp+=1; memcpy((*(p_map+i)).name,&temp,1); (*(p_map+i)).age=20+i; } if(shmdt(p_map)==-1) perror(" detach error "); } /********** testread.c ************/ #include #include #include #include typedef struct{ char name[4]; int age; } people; main(int argc, char** argv) { int shm_id,i; key_t key; people *p_map; char* name = "/dev/shm/myshm2"; key = ftok(name,0); if(key == -1) perror("ftok error"); shm_id = shmget(key,4096,IPC_CREAT); if(shm_id == -1) { perror("shmget error"); return; } p_map = (people*)shmat(shm_id,NULL,0); for(i = 0;i<10;i++) { printf( "name:%s\n",(*(p_map+i)).name ); printf( "age %d\n",(*(p_map+i)).age ); } if(shmdt(p_map) == -1) perror(" detach error "); } testwrite.c 创建一个系统 V 共享内存区,并在其中写入格式化数据;testread.c 访问同一个 系统 V 共享内存区, 读出其中的格式化数据。 分别把两个程序编译为 testwrite 及 testread, 先后执行./testwrite 及./testread 则./testread 输出结果如下: name: b age 20; age 24; name: g age 25; age 29; name: h age 26; name: I age 27; name: j age 28; name: k name: c age 21; name: d age 22; name: e age 23; name: f 通过对试验结果分析,对比系统 V 与 mmap()