簡體   English   中英

在退出父進程后,子進程無法讀取

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

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