2016-02-29 3 views
2

Я пытаюсь записать в именованный канал из процесса нижнего уровня и читать из трубы на верхнем уровне процесса.C - Именованная труба между процессом верхнего уровня и процессом нижнего уровня (лист)

Для этого я сначала создаю FIFO в процессе верхнего уровня, а затем используя цикл for, чтобы развить больше процессов. В цикле for я проверяю листовые процессы, и если это лист, я пишу в FIFO и ломаюсь от цикла. Затем, после цикла, я пытаюсь прочитать из FIFO в процессе верхнего уровня. Это не работает, моя программа просто застревает и останавливается после создания листового процесса.

Как отправить сообщение с листа обратно в верхний родительский процесс через FIFO?

КОД:

#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()); 

    //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); 

    //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 

      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[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, getpid(), getppid()); 

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

     } 
     else{ //parent 
      close(pfds[0]); 
      char hold[3]; 
      sprintf(hold,"%d",lev); 
      if(write(pfds[1], hold, 3) <= 0){ 
       perror("parent"); 
       exit(1); 
      } 

      wait(NULL); 
      return 0; 
     } 
    } 

    //read fifo 
    char buff[MAX_BUF]; 
    fd = open(myfifo,O_RDONLY); 
    read(fd,buff,MAX_BUF); 
    close(fd); 

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

ВЫВОД:

ALIVE: Level 3 process with pid=554, child of ppid=451. 
ALIVE: Level 2 process with pid=555, child of ppid=554. 
ALIVE: Level 1 process with pid=556, child of ppid=555. 
_ // <---- stalls here 
+1

Видя код, было бы полезно. – alk

+0

добавлен код и вывод – Dylan

+0

Код (по крайней мере) вызывает неопределенное поведение путем печати строки, отличной от '0', здесь:' printf («получено сообщение% s. \ N», buff); ' – alk

ответ

0

Все процессы подвешивают на "ждать()" вызова (т.е. ожидание одного из своих детей, чтобы выйти), за исключением последнего ребенок разветвлен ... который висит на «open (myfifo, O_WRONLY)» .... Последний ребенок будет продолжать висеть до тех пор, пока процесс не откроет fifo для чтения ...

+0

Как я могу сделать процесс верхнего уровня открытым для чтения? Если я поставлю его после цикла for, в котором работают процессы fork, цикл for никогда не заканчивается (застрял на последнем дочернем элементе), поэтому он никогда не читает. Если я поставил его перед циклом for, он попытается прочитать до того, как что-то напишет на него и никогда не выполнит цикл. Если я попытаюсь прочитать в цикле for в родительской части, другие родители также смогут прочитать ее, а не только верхний родитель. – Dylan