簡體   English   中英

在某些情況下,在管道中執行第二個/最后一個命令后,進程掛起

[英]Process hangs after executing the second/last command in pipe in certain cases

我正在使用管道,fork和exec來實現用戶外殼程序。 問題是它在某些情況下不起作用。 例如,如果我有ls | 頭,但不適用於ls | 貓。 它會顯示cat的輸出,但此后將僅掛起而不返回提示。

參考代碼,我將輸入存儲在c-> args [0]中,為此我派生了一個孩子並執行它。

我知道第二位執行人員仍在等待EOF,但是在此之前關閉文件描述符沒有幫助。

經歷類似的問題,我也嘗試在等待之前但在這樣做之后關閉父進程中的文件描述符。 頭不起作用。 我已經在下面發布了相關功能。

    void executeProcess(Cmd c,int noofcmds)
{
//    printf("Will be entering fork procedure \n");
     int cmdNo;
     pipe(fd);
  for (cmdNo = 0;cmdNo < noofcmds; cmdNo ++)
  { 

    int processid = fork();
    pid_t childpid;
//    printf("Process id %d\n",processid);
    if (processid == 0)
      { 
//  if (noofcmds != 1)
//       {  
    if (cmdNo == 0)
     {
       printf("Inside first child \n");
       close(fd[0]);
       dup2(fd[1], 1);
//     close(fd[0]); 
     } else if (cmdNo == noofcmds-1)
     {  
       close(fd[1]);
       dup2(fd[0], 0);
//         close(fd[0]);

     }
//  close(fd[1]);
//  close(fd[0]);
        if (execvp(c->args[0],c->args) < 1)
     { printf("Error\n");
     }
      } else 
      {
//  printf("Waiting in parent\n");
//  close(fd[0]);
//  close(fd[1]);

    int status;
    int returnedpid;
    wait(&status);
        printf("Returned after waiting\n");
//  close(fd[0]);
//  close(fd[1]);   
      }
    c = c->next;
//  close(fd[0]);
//  close(fd[1]);
  } // end of for
}

ls | cat看事件的順序ls | cat ls | cat這就是現在發生的事情:

1)在父級中創建管道。
2) ls孩子催生
3)父母等待ls完成
4)產生cat
5)父母等待cat完成

正如您所注意到的,在5)中,父母仍然打開了管道,所以cat永遠都不會完蛋。

當您在代碼的父部分中關閉它時,它會在3)之前關閉。 因此,在cat啟動時,管道已不存在-> cat沒有輸出。

您需要在4)之后用類似的方法將其關閉:

...
else  // in parent
{
    // printf("Waiting in parent\n");

    if (cmdNo == 1)  // second child is spawned, can close the pipe now.
    {
        close(fd[0]);
        close(fd[1]);
    }

    int status;
    wait(&status);
    printf("Returned after waiting\n");
}

代碼需要更多的工作來處理管道中的兩個以上命令,但是您明白了...

提示:找到一個自動縮進代碼的編輯器,這將使您的生活更加輕松!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM