任务:主进程打开一段共享内存,fork出8个子进程分别将共享内存map到各自虚拟地址空间中,每个子进程都需要将共享内存中的一个数值加一。
参考文档:
http://man7.org/linux/man-pages/man3/shm_open.3.html
http://man7.org/linux/man-pages/man2/mmap.2.html
http://man7.org/linux/man-pages/man7/inode.7.html
http://man7.org/linux/man-pages/man2/ftruncate.2.html
代码实现:
#include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #define MAPPING_SIZE 4096 int main (int argc,char* argv[]){ int mapfd; const char* mapname = "/number"; mapfd = shm_open(mapname,O_RDWR|O_CREAT,S_IRUSR | S_IWUSR); if(mapfd == -1){ perror("shm_open fail"); exit(EXIT_FAILURE); } // ftruncate可以用来设置共享内存到指定大小 if(ftruncate(mapfd,MAPPING_SIZE) == -1){ perror("ftruncate fail"); close(mapfd); exit(EXIT_FAILURE); } int stat,cid,n,procCount=0,maxProcCount=8; for(n = 0;n<maxProcCount;++n){ cid = fork(); if (cid == -1){ perror("fork fail"); continue; } if(cid == 0){ void* sp = mmap(NULL,MAPPING_SIZE,PROT_READ | PROT_WRITE,MAP_SHARED,mapfd,0); if (sp == NULL){ perror("mmap fail"); close(mapfd); _exit(EXIT_FAILURE); } int * num = (int*)sp; (*num)++; printf("Process %d: %d ",getpid(),*num); if(munmap(sp,MAPPING_SIZE) == -1){ perror("munmap fail"); } close(mapfd); _exit(EXIT_SUCCESS); } ++procCount; } while(procCount--){ cid = wait(&stat); if(cid == -1){ perror("wait fail"); break; } printf("%d cid %d exit. ",procCount,cid); } close(mapfd); // 如果不执行shm_unlink则多次执行程序的输出是递增的,共享内存被重复利用了 shm_unlink(mapname); }
执行结果:
[root@centos7 c]# gcc process.c -lrt -o proc
[root@centos7 c]# ./proc Process 5941: 1 Process 5942: 2 Process 5943: 3 Process 5944: 4 Process 5946: 5 Process 5947: 6 Process 5945: 7 7 cid 5941 exit. 6 cid 5942 exit. 5 cid 5943 exit. 4 cid 5944 exit. 3 cid 5946 exit. 2 cid 5947 exit. 1 cid 5945 exit. Process 5948: 8 0 cid 5948 exit.