FIFO - 从顶层进程读取,从底层进程写入

时间:2016-03-02 21:05:41

标签: c ipc named-pipes fifo

我试图在我的程序的顶级和底级进程之间进行通信。首先我创建FIFO,然后我有一个for循环到fork n进程。在for循环中,我检查进程是否是底层进程,如果是,我写入FIFO。

我对底层进程写入后如何从FIFO读取感到困惑。如果我在循环之前尝试读取,则循环永远不会执行,因为没有写入任何内容。如果我在循环期间尝试读取,在代码的父节中,其他父节点也可以读取它。如果我尝试在for循环之后读取,代码循环永远不会完成,因为它在最后一个孩子尝试写入时卡住了。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>

#define MAX_BUF 1024

int main(int argc, char **argv){

    int numprocs = atoi(argv[1]);
    int lev = numprocs;
    fprintf(stdout,"ALIVE: Level %d process with pid=%d, child of ppid=%d.\n", lev, getpid(), getppid());
    int currpid = getpid();

    //create shared memory
    const int SIZE = numprocs * sizeof(int);
    const char *name = "dleggio1OS";
    int shm_fd;
    int *ptr;
    shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
    ftruncate(shm_fd, SIZE);
    ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
    *ptr = getpid();

    //create fifo
    int fd;
    char *myfifo = "/tmp/dleggio1fifo";
    mkfifo(myfifo, 0666);
    //read fifo
    /*char buff[MAX_BUF];
    fd = open(myfifo,O_RDONLY);
    read(fd,buff,MAX_BUF);
    printf("process %d received %s message.\n",getpid(),buff);
    close(fd);*/


    //spawn procs
    int i;
    for(i = 1; i < numprocs; i++){
        lev--;
        int pfds[2];
        char buf[30];
        if(pipe(pfds) == -1){
            perror("pipe");
            exit(1);
        }
        pid_t pid;


        if((pid = fork()) < 0){
            perror("fork");
            exit(1);
        }

        if(pid == 0){ //child

            ptr[i] = getpid();

            close(pfds[1]);
            if(read(pfds[0], buf, 3) <= 0){
                perror("child");
                exit(1);
            }
            int check = atoi(buf);
            fprintf(stdout,"ALIVE: Level %d process with pid=%d, child of ppid=%d.\n", check, ptr[i], ptr[i-1]);

            if(check == 1){ //leaf
                //write to fifo
                fd = open(myfifo, O_WRONLY);
                write(fd,"leaf",sizeof("leaf"));
                close(fd);
                return 0;
            }

        }
        else{ //parent
            close(pfds[0]);
            char hold[3];
            sprintf(hold,"%d",lev);
            if(write(pfds[1], hold, 3) <= 0){
                perror("parent");
                exit(1);
            }
            //read fifo
            /*char buff[MAX_BUF];
            fd = open(myfifo,O_RDONLY);
            read(fd,buff,MAX_BUF);
            printf("process %d received %s message.\n",getpid(),buff);
            close(fd);*/

            wait(NULL);
            return 0;
        }
    }

    //read fifo

    /*char buff[MAX_BUF];
    fd = open(myfifo,O_RDONLY);
    read(fd,buff,MAX_BUF);
    printf("received %s message.\n",buff);
    close(fd);*/

    shm_unlink(name);
    unlink(myfifo);
    return 0;
}

1 个答案:

答案 0 :(得分:0)

  

如果我在循环期间尝试读取,在代码的父节中,   其他家长也可以阅读。

它们都可以从FIFO读取,因为您在分支任何进程之前创建FIFO;因此,他们都使用相同的。如果您希望每个父/子对都有一个只有他们可以使用的私有FIFO,那么您需要在循环内移动mkfifo()调用并为每个{{创建一个唯一名称的FIFO) 1}}。