进程间通信:共享内存

任务:主进程打开一段共享内存,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\n",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.\n",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.

 

posted @ 2019-03-08 14:41  zerofl-diary  阅读(599)  评论(0编辑  收藏  举报