首页 > 代码库 > 父子进程通过mmap进行通信

父子进程通过mmap进行通信

本来打算使用pipe进行父子进程之间的数据交互(应用场景是父进程向多个子进程分发数据,子进程进行处理);但是担心pipe的性能,转而使用mmap实现。

废话少叙,上代码。

#include <stdio.h>#include <sys/types.h>#include <signal.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#include <sys/mman.h>#include <fcntl.h>#define SHMFILE "shm.data"typedef struct cell_t {    int state;    #define CELL_READY  1    #define CELL_CLEAR  0    int size;    char    data[64];} cell_t;int main(void) {    signal( SIGCHLD, SIG_IGN );        int i, ret = 0;    int fd = open(SHMFILE, O_CREAT | O_RDWR | O_TRUNC, 0600);    if ( fd < 0 ) {        fprintf(stderr, "fail to open %s -- %s\n", SHMFILE, strerror(errno));        return  2;    }    int n_cells = 8;    int shm_size = sizeof(cell_t) * n_cells;    off_t off = lseek(fd, shm_size, SEEK_END);    if ( off != (off_t)shm_size ) {        fprintf(stderr, "fail to seek %s (got:%ld want:%d) -- %s\n", SHMFILE, off, shm_size, strerror(errno));        return  3;    }    ret = write(fd, "", 1);    if ( ret < 0 ) {        fprintf(stderr, "fail to write %s -- %s\n", SHMFILE, strerror(errno));        return  5;    }    cell_t* cell = (cell_t *) mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);    if ( cell == NULL ) {        fprintf(stderr, "fail to mmap %s -- %s\n", SHMFILE, strerror(errno));        return  7;    }    for (i=0; i<n_cells; i++) {        memset( cell + i, 0, sizeof(cell_t) );    }    int id = 3;    int pid = fork();    if (pid < 0) {        fprintf(stderr, "fail to fork child -- %s\n", strerror(errno));        return  1;    }    else if (pid == 0) {        // child process        pid = getpid();        fprintf(stdout, "\tC#%d I am here ...\n", pid);                cell_t* c = &cell[id];                for ( i=0; i<5; i++ ) {            if ( c->state == CELL_READY ) {                fprintf(stdout, "\tC#%d size=%d data=http://www.mamicode.com/‘%s‘/n", pid, c->size, c->data);                c->state = CELL_CLEAR;                break;            }            sleep(1);        }        fprintf(stdout, "\tC#%d byebye\n", pid);        munmap(cell, shm_size);        close(fd);        exit(0);    }    pid = getpid();    fprintf(stdout, "P#%d I am here ...\n", pid);    sleep(1);    {        cell_t* c = &cell[id];        char*   data = "http://www.mamicode.com/Hello,World.";        c->size = strlen(data);        memmove( c->data, data, c->size );        c->state = CELL_READY;        fprintf(stdout, "P#%d cell->state=%d\n", pid, c->state);        sleep(5);        fprintf(stdout, "P#%d cell->state=%d\n", pid, c->state);    }    fprintf(stdout, "P#%d byebye\n", pid);    munmap(cell, shm_size);    close(fd);    return  0;}