当我从 c 中的分叉 child exec() 时会发生什么

what happens when I exec() from a forked child in c

假设我有进程 foo 和可执行文件 bar。 foo 调用 fork() 现在我有两个,调用它们 foo_parent 和 foo_child.

我不太明白 foo_child/bar 发生了什么。 foo_child在内存中被bar覆盖了吗?是否启动了一个新的 bar 进程并给出了 foo_child 的 pid? bar foo_child 的 child 和 foo_child 只是将 return 传递给 foo_parent 吗?

我知道当 foo_parent 等待后获得退出状态时,这是 bar 的 exit() 调用的结果,但我不太了解发生了什么 "under the hood," 因为它是。

foo_child 的过程被 bar 完全取代。它具有相同的 PID,许多其他属性在 foo_childbar 中相同,但可执行文件是重新启动的。进程bar仍然是foo_parent的子进程,所以foo_parent可以获得它的退出状态等

请注意,exec*() 函数家族永远不会 return 如果它们成功。如果他们return,他们就失败了。

"foo calls fork() and now I have two, call them foo_parent and foo_child."

减少混淆:您仍然有进程 foo(父进程),现在您还有一个子进程 (foo_child)。

"Is foo overwritten in memory with bar?"

当foo_child调用exec()时,其内存space被bar的内存覆盖。它保留了 foo 的一些东西。特别是,在 foo 中打开的文件描述符(并且不是 close-on-exec)仍然在 bar 中打开,它还继承了 foo 的一些信号处理配置(有关详细信息,请参阅 exec* 的手册页)。

"Is a new bar process started and given foo_child's pid?"

有点,不完全是。新进程 foo_child,具有自己的 pid 和内存 space,在您 fork 时开始。在分叉时它有一份 foo 的内存 space。当它调用 exec(bar) 时,它的内存 space 被 bar 覆盖并运行 bar 而不是 foo 的可执行代码。

"Is bar a child of foo_child and foo_child just passes the return on to foo_parent?"

不,bar(即 - foo_child 现在正在执行 bar)是 foo 的子进程,其退出值可以返回给 foo。