[英]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.