2016-03-02 132 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