什么时候自己调用 fork() 和 exec()?

qui*_*uil 9 system-calls fork exec

我正在学习fork()exec()命令。它似乎fork()exec()通常被称为在一起。(fork()创建一个新的子进程,并exec()用一个新的进程映像替换当前进程映像。)但是,在什么情况下您可以单独调用每个函数?有这样的场景吗?

thr*_*rig 22

当然!“包装器”程序中的一个常见模式是做各种事情,然后只用一个exec调用(没有分叉)用其他程序替换自己

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"
Run Code Online (Sandbox Code Playgroud)

一个真实的例子是GIT_SSH(尽管如果您不想执行上述包装程序方法git(1),也可以提供GIT_SSH_COMMAND)。

Fork-only 用于生成一堆典型的工作进程(例如httpdfork 模式下的Apache (尽管 fork-only 更适合需要消耗 CPU 的进程,而不是那些挥动拇指等待网络 I/O 发生的进程) ) 或用于OpenBSD 上和其他程序使用的权限分离sshd(无 exec)

$ doas pkg_add pstree
...
$ pstree | grep sshd
 |-+= 70995 root /usr/sbin/sshd
 | \-+= 28571 root sshd: jhqdoe [priv] (sshd)
 |   \-+- 14625 jhqdoe sshd: jhqdoe@ttyp6 (sshd)
Run Code Online (Sandbox Code Playgroud)

所述root的sshd已对客户端连接两岔断(28571)的本身的副本,然后对权限分离另一个副本(14625)。


Jde*_*eBP 14

有很多。

调用程序fork()没有exec()通常以下产卵子的模式工作进程进行单独处理各种任务的主要原因之一。你会在程序发现这是改变的dhclientphp-fpmurxvtd

exec()没有调用的程序fork()链式加载,用不同的程序映像覆盖其进程。链加载实用程序有一个完整的亚文化,它们执行特定的操作来处理状态,然后执行另一个程序以在修改后的进程状态下运行。此类实用程序在daemontools服务和系统管理工具集系列中很常见,但不仅限于这些。几个例子:

该家庭daemontools的工具集有很多这样的工具,从machineenv通过find-matching-jvmruntool