[英]Child process cannot read after the exiting of parent process
在通過函數execvp()
分叉和執行子程序之后,父進程退出。 但是這會導致子進程中的函數fgets()
立即返回,而不等待stdin
。
我想父進程的退出會向子進程發送一些信號,這會使fgets()
函數返回。 有人可以為我解釋一下嗎?
兒童計划代碼:
/* cc child.c -o child */
int main () {
char buffer[10];
fgets(buffer, 10, stdin);
printf("This is what child program read:\n%s", buffer);
}
父母計划代碼:
/* cc parent.c -o parent */
int main (int argc, char **argv) {
pid_t pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
else if (pid == 0) {
execvp(*(argv+1), argv+1);
}
else {
// while(1); if while(1) or wait() is used, child process can wait for input
exit(1);
}
}
在zsh shell中:
zsh>: ./parent ./child
zsh>: This is what child program read: // read nothing and print nothing
終端由前台進程組控制。 當shell調用父對象時,它使父對象成為前台進程組的領導者。 孩子繼承該組並可以訪問終端。
但是,當父進程退出時,shell將取回終端的控制權並成為前台進程組的領導者。 子進程不再位於前台進程組中,因此無法訪問終端。 在這種情況下, fgets()
將返回NULL
並將設置錯誤代碼。
如果您從終端以外的某個位置(例如管道)接收輸入,那么您將看到程序按預期工作。 例如:
$ echo test | ./parent ./child
所以只有當輸入來自終端時才會出現此問題。
回想起來 ,如果檢查了fgets錯誤代碼,回答這個問題會更加直截了當。 在這種情況下,fgets返回null,但是您需要檢查feof()
和/或ferror()
以確定這是否意味着文件的末尾已到達(stdin已關閉)或存在錯誤。 在這種情況下,NULL意味着存在EIO
錯誤。
早期的錯誤答案(請參閱注釋線程以獲得解釋,因為冗長的討論而留在此處):當您進行fork時,子進程繼承stdin等。當父進程退出時,它會關閉stdin,因此子進程嘗試從關閉狀態讀取描述符,什么都沒得到 通過添加對wait()
的調用,可以保持stdin打開,這樣可以讓您的子程序按預期工作。
您應該在打印緩沖區之前檢查fgets()的返回值。 檢查fgets是否不返回NULL,然后僅打印緩沖區。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.