fork进程终止后没有bash指示器提示

fork进程终止后没有bash指示器提示

我正在看书Unix 环境中的高级编程。有一个测试程序可以测试该fork功能。它在我的 Ubuntu 上运行良好。但令我困惑的是,为什么子进程退出后没有命令指示符提示。原来的程序如下所示。

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{
  pid_t pid;
  if ((pid = fork()) < 0)
  {
    printf("fork error.\n");
    return 1;
  }
  else if (pid == 0)
  {
    if ((pid = fork()) < 0)
    {
      printf("fork error.\n");
      return 1;
    }
    else if (pid > 0)
    {
      printf("first child %d exit.\n", getpid());
      exit(0);
    }
    sleep(2);
    printf("second child %d has parent pid = %d.\n",getpid(),  getppid());
    exit(0);
  }

  printf("waitid %d.\n", pid);
  if (waitpid(pid, NULL, 0) != pid)
  {
    printf("waitid error.\n");
    return 1;
  }
  printf("process %d will exit..\n", getpid());

  exit(0);
}

然后我跑

jerryli@ubuntu:~/project/unix$ ./p183.o
waitid 2256
first child 2256 exit.
process 2255 will exit..
jerryli@ubuntu:~/project/unix$ second child 2257 has parent pid = 1.

上面一行提示后,没有任何继续。我希望它会显示

jerryli@ubuntu:~/project/unix$

为了获得上述指标,我必须输入Enter.

你能知道原因吗?是因为第二个子进程的父进程变成了系统init进程吗?

答案1

fork在后台启动一个进程。当前台进程(调用 的进程fork)终止时,调用 shell 会收到通知,并显示一个新的提示符。 shell 是原始前台进程的父进程;它不是任何一个分叉进程的父进程。

原始进程和分叉进程的执行顺序并不固定,但由于 2 秒的延迟,不太可能出现任何相关的偏差。在您的测试中,时间线恰好是:

  1. fork原始进程中的第一个子进程。
  2. fork第一个孩子中的第二个孩子。
  3. 原始进程打印waitid跟踪并开始waitpid调用以等待第一个子进程。
  4. 第一个子进程打印其exit踪迹,然后退出。
  5. 原始进程收到子进程死亡的通知,并且其waitpid调用返回。
  6. 原始进程打印其will exit痕迹。
  7. shell 会收到原始进程已退出的通知并打印其提示符。
  8. 不到 2 秒后,sleep第二个子级中的调用完成,第二个子级打印其has parent跟踪。

shell 不会收到关于最后事件的任何通知,因为它不是终止进程的父进程。无论如何,它已经显示了一个提示符,正在等待您输入新命令;它没有理由做任何事情(如果您正在输入命令,这可能会造成干扰)。

答案2

按照@Gilles的回答,我打算实现与@jerry要求类似的事情:1.在分叉之前存储终端PID 2.在每组打印之后发送SIGINT以“推动”终端以显示提示

很脏,但似乎可以完成工作

相关内容