对于这样一个菜鸟问题,我很抱歉,但我不熟悉 Unix(系统调用)。我试图理解 fork 命令,我知道如果它的子进程或返回 pid 的子 ID,fork 命令返回 pid 0。我想知道一个进程一次只能有一个子进程并返回它的 pid 还是可以有多个子进程?(实际上我无法想象如果它有多个子进程,如何返回 pid 和哪个 pid?)
3 回答
每次调用都会fork()
创建一个子进程,并且只返回该单个进程的 PID,但没有什么可以阻止您fork()
多次调用以创建多个子进程。
不要忘记wait() 或 waitpid()让您的分叉子进程退出,否则您可能会遇到僵尸进程。
Fork不是 Unix命令,而是在fork(2) Posix 手册页中记录的系统调用。Linux 手册页是fork(2) -linux-这里。
成功时,fork
系统调用返回两次:一次在(调用)父进程中(它给出pid
子进程的 ),一次在新创建的子进程中(它给出 0)。否则,这两个进程是克隆(并且一些 Linux 实现fork
在 Linux 特定的clone(2)系统调用之上实现了一个实现)并且正在执行具有几乎相同状态的相同程序(实际上是两个几乎相同的副本)。两个(父子)进程同时运行(作为内核调度的任务,可能在不同的处理器内核上并行运行)。
系统fork(2)
调用可能(很少)失败(例如,为了避免分叉炸弹),例如,当已达到使用setrlimit(2)RLIMIT_NPROC
系统调用设置的限制时。当它失败时,系统调用返回 -1 并且你应该检查. 检查每个系统调用的失败是一种很好的做法,也不例外。fork
errno
fork
Fork 是启动进程的常用方式,所有 [除了一些罕见的例外] 用户进程都是由某个fork
系统调用(或类似vfork(2)
, or的变体clone(2)
)启动的。特别是,当您在 shell(例如,可能在终端仿真器中运行)中键入命令(例如ls
或)时,shell 通常会先 -ing 自身,然后-ing 所需的程序(例外是 shell 内置命令,如)。date
/bin/bash
fork
execve
cd
请注意,Linux 系统上的几乎所有进程都是由fork
. 例外是内核启动的进程,如/sbin/init
or /sbin/modprobe
...
您可以fork
多次调用(典型的 shell 实现对每个命令都执行此操作,除了内置命令,如cd
;您可能想研究自由软件 shell 的源代码,sash
如 bash
您最终应该使用wait(2)或waitpid(2)
系统调用等待子进程。进程可以使用execve(2)系统调用更改其可执行文件和地址空间。它的地址空间可以使用mmap(2)和相关的系统调用来改变。
您可能想用它strace -f
来了解系统调用是由什么进行的,例如通过某些 shell。
I strongly recommend reading the Advanced Unix Programming book and the Advanced Linux programming book (the later being available on line with some free license).
Same answer as others with a twist: If each process could create only one child (use fork() only once), what would that mean for the lineage of processes? It would mean that there is exactly one line, say, init -> login -> shell -> ls
. Would you like such a system? What is your conclusion?