[英]Reading writes of child process from parent process
在以下代碼中,我分叉 5 次以創建 5 個子進程,每個子進程接收
來自父進程的字符串,子進程將child-i
寫回父進程
其中i
是子進程 for 循環中的循環計數器。 當我運行這個程序時,我
只看到child-0
然后程序掛起。
int main(int argc, char *argv[])
{
int num_processes = 5;
int pipefd[2 * num_processes][2];
pid_t cpid;
char buf;
if (argc != 2)
{
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}
for (int i = 0; i < 2 * num_processes; i++)
{
if (pipe(pipefd[i]) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < num_processes; i++)
{
cpid = fork();
if (cpid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0)
{ /* Child reads from pipe */
close(pipefd[i][1]); /* Close unused write end */
while (read(pipefd[i][0], &buf, 1) > 0)
{
}
char buf[12];
snprintf(buf, 12, "child-%d", i);
write(pipefd[num_processes + i][1], buf, strlen(buf));
write(STDOUT_FILENO, "\n", 1);
close(pipefd[i][0]);
close(pipefd[num_processes + i][0]);
break;
}
else
{ /* Parent writes argv[1] to pipe */
/* Close unused read end */
write(pipefd[i][1], argv[1], strlen(argv[1]));
close(pipefd[i][1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
char buf;
while (read(pipefd[num_processes + i][0], &buf, 1) > 0)
{
write(STDOUT_FILENO, &buf, 1);
}
close(pipefd[num_processes + i][0]);
}
}
_exit(EXIT_SUCCESS);
}
當我運行這個程序時,我只看到
child-0
,然后程序掛起。
是的,因為父進程無限期地等待從pipefd[num_processes + i][0]
讀取更多數據。 考慮一下:
while (read(pipefd[num_processes + i][0], &buf, 1) > 0)
從代碼的其他部分來看,您似乎意識到在寫入端關閉之前,進程在從 pipe 讀取時不會看到 EOF,但也許您沒有認識到寫入端的所有句柄都需要先關閉基礎打開文件描述已關閉。 或者您可能根本沒有考慮到父進程在它創建的每個 pipe 的每一端都有一個副本。 只要它打開了pipefd[num_processes + i][1]
,它就永遠不會在pipefd[num_processes + i][0]
上看到 EOF,無論孩子做什么。
作為使用管道的最佳實踐,所涉及的每個進程都應在不再需要保持打開時立即關閉每個 pipe 端。 尤其是寫端,因為不關閉它們很容易讓你陷入更深的麻煩,但是讓讀端打開會產生資源泄漏,這也會給你帶來麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.