在 Linux 上双击应用程序时谁会分叉?

在 Linux 上双击应用程序时谁会分叉?

所以我知道当我在 shell 中运行可执行文件时,shell 会将其分叉为子进程,然后执行以获取可执行文件的程序和数据内存。因此,如果我的 shell 现在关闭/退出,那么其所有关联的子进程也会被终止。

我读到,在 Linux 中,每个进程都是通过 fork() exec() 创建的。我很好奇,想知道每当通过双击图标启动应用程序时,哪个进程 forks() exec() 它,我理解它是某个 OS 进程,我想知道哪个

谢谢你!

回答 追溯到 /sbin/upstart

答案1

首先,术语

可执行文件是系统中的简单文件。进程就是执行可执行文件中嵌入的程序的简单过程。


你说得对可执行文件的启动方式

  1. 父进程(已存在)forks 本身,从该点开始引入两个执行流。一个位于父进程中,另一个位于新进程中。
  2. 新的(子)进程将自身静音,以执行要运行的可执行文件的程序。这是使用系统调用exec家庭。

以图形界面为例,您在其中双击一个可执行图标,然后您就可以从显示所单击图标的进程中分叉出可执行文件,其源代码基本上如下:

const char *exe_path = taken_from_icon();
int pid = fork();
if(pid == 0)
{
    // I am the new child
    execl(exe_path, exe_path, NULL);
    // exec only return in case of failure
    exit(EXIT_FAILURE);
}
// I am the graphical interface,
// Continue and wait for another clic

死亡和父母身份孩子的情况并不像你所说的那样。

基本上 — — 当父进程仍然存在时 — — 子进程是其父进程的子进程(是的!-) 它的 PPID(父进程 ID)设置为分叉它的仍然存在的进程。

当父进程死亡时,情况会发生变化。子进程继续存在,但其 PPID 被设置为仍处于活动状态的祖父进程。由于init进程永远不会死亡,因此总会有一个。


当 shell 本身死亡时,shell 子进程也会死亡,这是很特殊的一件事。我认为有两个原因:

  • 第一个:shell 通常会维护它所分叉的 PID 列表。当 shell 死机时,它会杀死所有 PID。主流 shell 有一个disown内置命令,用于从此列表中删除子进程,并在 shell 死机时让其存活。请参阅bash 手册页

    默认情况下,shell 在收到 SIGHUP 后退出。在退出之前,交互式 shell 会将 SIGHUP 重新发送给所有正在运行或已停止的作业。已停止的作业将收到 SIGCONT 以确保它们收到 SIGHUP。要防止 shell 向特定作业发送信号,应使用 disown 内置命令将其从作业表中删除(请参阅下面的 SHELL 内建命令),或使用 disown -h 将其标记为不接收 SIGHUP。

  • 第二种:shell 子进程通常通过管道将其 stdin、stdout 和 stderr 连接到 shell 本身。如果 shell 停止使用子进程的 stdout(通常用于打印),或关闭其管道末端,则子进程在向其 stdout 写入时可能会失败,从而可能将其阻塞或终止。

相关内容