2016-03-02 73 views
0

我试图在我的程序的顶层和底层过程之间进行通信。首先我创建FIFO,然后我有一个for循环fork n进程。在for循环中,我检查一个进程是否是底层进程,如果是,则写入FIFO。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; 
} 

回答

0

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

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

+0

我怎样才能得到顶级父母和底层的孩子有一个私人的FIFO? – Dylan

+0

在每次循环迭代中,创建一个具有唯一名称的新FIFO(例如,将循环计数器添加到名称末尾),并让父/子使用该名称。每次迭代将只知道它的私有FIFO的名称,并且将无法访问任何其他人的名称。 – bta