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


9

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


2
传统的前炸弹:while(1)fork(); 占用系统资源。
约书亚

Answers:


22

当然!“包装器”程序中的常见模式是先做各种事情,然后仅通过exec调用(没有派生)将其替换为其他程序。

#!/bin/sh
export BLAH_API_KEY=blub
...
exec /the/thus/wrapped/program "$@"

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

仅产生一个典型的工作进程时(例如,Apache httpd以fork模式使用(虽然仅fork更好地适合需要消耗CPU的进程,而不是那些费力地等待网络I / O的进程)的进程)才使用Fork-only。)或权限分离使用sshd在OpenBSD(没有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)

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


14

有很多。

fork()不带调用的程序exec()通常遵循一种生成子工作者进程的模式,以在与主进程不同的进程中执行各种任务。你会在程序发现这是改变的dhclientphp-fpmurxvtd

exec()不进行调用的程序fork()就是链式加载,将其过程覆盖到另一个程序映像中。整个链加载实用程序的亚文化是对进程状态做特定的事情,然后执行另一个程序以修改后的进程状态运行。这些实用程序在daemontools服务和系统管理工具集的家族中很常见,但不仅限于此。一些例子:

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


2

除了其他的答案,调试,使用ptrace,一般使用之间的差距forkexec。被调试对象应该用标记自己,PTRACE_TRACEME以指示其父进程(调试器)正在跟踪它。这是给调试器所需的权限。

因此,调试器将首先派生自己。孩子会打电话ptracePTRACE_TRACEME,然后再打电话给exec。现在,父执行程序可以跟踪子执行程序的哪个程序。


在fork和exec之间有许多处理事务的示例,最常见的是重定向I / O(例如,设置管道)。但是问题是关于根本没有任何执行程序的情况下执行fork。
Barmar

0

没有叉子的执行

您要执行此操作的原因至少有两个:

  1. 链条加载。当前过程映像将替换为其他内容。
  2. 重新启动当前正在运行的程序(例如,当您使用SIGHUP或这样的服务器进程时,可能会重新加载所有内容并进行全新的启动)。以某种方式,人们可能会认为这是链加载,只是碰巧与同一程序有关。

无执行叉

这就是每个守护程序每次启动都要做的事情(实际上是两次)。这可以做几件事,其中shell不会挂起(因为shell等待的原始进程终止),并且守护进程不再由终端控制,因此关闭shell窗口不会杀死该守护进程。

另一个常见的用途是分叉工人的孩子,这是25年前由apache网络服务器而闻名的(如今,由于非常容易出现雷电群问题,现在不再被认为是最新技术,但是它确实提供了尽可能简化最强大的服务器)。

另一个常见用途是创建一致的快照。fork不仅创建一个进程,它还复制(理论上,实际上它仅标记页面写时复制)地址空间。这(从原子上)创建了完整程序数据的快照,父级无法再对其进行修改。
一些程序利用了这一点。例如,redis将数据保存到磁盘(处于一致状态),同时同时修改数据集。这仅适用,因为fork创建了一个一致的快照,看不到父进程所做的修改。


如今,它实际上已经很少了,大多数都没有作为标准来实现,或者有一种常用的模式。分叉会导致准备失配恐怖,这是一个错误,也是妖魔化谬误的错误之一。这个错误最终终于失宠了。
JdeBP
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.