2014-04-23 50 views
2

我正在使用pipe fork和exec來爲任何兩個shell程序實現通用管道。我正在使用ls | grep來測試它。它工作,數據被複制到grep,grep搜索匹配,然後將它們輸出到stdout。但之後,該程序只是掛起。程序在使用管道,fork和exec之後掛起

這是我檢測到管道時執行的代碼。我叉,然後再次fork,因爲我希望第一個fork的父進程在exec調用後繼續運行。我相信由於調試代碼,在執行grep的exec()調用之後,什麼也沒有發生。

if(pipeFlag == 1){ 
    pipe(fd); 
    PID = fork(); 
     if (PID == 0){//child process 
    fPID = fork(); 
    if(fPID == 0){//child of child 
     printf("in child of child\n"); 
     dup2(fd[1], 1); 
       execvp(command, argv);//needs error checking 
       printf("mysh: %s: command not found\n", argv[0]); 
      exit(EXIT_FAILURE); 
    } 
    if(fPID > 0){//parent of 2nd child 
     printf("in parent of 2nd child\n"); 
     dup2(fd[0], 0); 
       execvp(command1, argv1);//needs error checking 
       printf("mysh: %s: command not found\n", argv[0]); 
      exit(EXIT_FAILURE); 
    } 
    if(PID == -1){ 
       printf("ERROR:\n"); 
       switch (errno){ 
        case EAGAIN: 
        printf("Cannot fork process: System Process Limit Reached\n"); 
       case ENOMEM: 
        printf("Cannot fork process: Out of memory\n"); 
       } 
       return 1; 
    } 
     } 
     if(PID > 0){//parent 
      wait(PID, 0, 0); 
    printf("in outer parent\n"); 
     } 
     if(PID == -1){ 
      printf("ERROR:\n"); 
      switch (errno){ 
       case EAGAIN: 
       printf("Cannot fork process: System Process Limit Reached\n"); 
      case ENOMEM: 
       printf("Cannot fork process: Out of memory\n"); 
      } 
      return 1; 
     } 
} 
+2

看起來這也有類似的問題,你可以解決從那裏只是複製 - http://stackoverflow.com/questions/916900/having-trouble-with-fork-pipe-dup2-and -exec-in-c?rq = 1 – Soren

+0

儘管他從未找到答案。 – user1768079

回答

0

下面是我對該問題的解決方案。我不確定這是否是一個永久的解決方案。我甚至不能100%確定,如果我的推理爲什麼這個工程和以前的代碼不是不是。我所做的只是將等待管道(grep)輸入的命令切換到父進程,以及將輸出寫入管道(ls)的命令傳遞給子進程。

我的推理爲什麼這個作品是這樣的:我正在測試ls | grep,ls在grep的子進程設置完成之前寫入管道,因此從未關閉管道,並且grep從未收到EOF。通過更改它們的位置,grep已準備就緒,並等待ls寫入到運行ls設置的進程的時間。我相信這是一個非常不完美的解決方案,所以對於將來閱讀此內容的任何人,我希望您能提供更好的答案。如果我的理由爲什麼這是正確的,那麼我可以考慮很多條件,這些條件仍然可能會搞砸。

if(pipeFlag == 1){ 
    pipe(fd); 
    PID = fork(); 
     if (PID == 0){//child process 
    fPID = fork(); 
    if(fPID == 0){//child of child 
     printf("in child of child\n"); 
     dup2(fd[0], 0); 
       execvp(command1, argv1);//needs error checking 
       printf("mysh: %s: command not found\n", argv[0]); 
      exit(EXIT_FAILURE); 
    } 
    if(fPID > 0){//parent of 2nd child 
     printf("in parent of 2nd child\n"); 
     dup2(fd[1], 1); 
       execvp(command, argv);//needs error checking 
       printf("mysh: %s: command not found\n", argv[0]); 
      exit(EXIT_FAILURE); 
    } 
    if(PID == -1){ 
       printf("ERROR:\n"); 
       switch (errno){ 
        case EAGAIN: 
        printf("Cannot fork process: System Process Limit Reached\n"); 
       case ENOMEM: 
        printf("Cannot fork process: Out of memory\n"); 
       } 
       return 1; 
    } 
     } 
     if(PID > 0){//parent 
      wait(PID, 0, 0); 
    printf("in outer parent\n"); 
     } 
     if(PID == -1){ 
      printf("ERROR:\n"); 
      switch (errno){ 
       case EAGAIN: 
       printf("Cannot fork process: System Process Limit Reached\n"); 
      case ENOMEM: 
       printf("Cannot fork process: Out of memory\n"); 
      } 
      return 1; 
     } 
}