我很抱歉这样一个noobie问题,但我不熟悉Unix(系统调用)。我试图理解fork命令,我知道fork命令返回pid 0,如果它的子进程或返回子id的pid。我想知道一个进程一次只能有一个子进程并返回它的pid或者可以有多个子进程?(实际上我无法想象它是否有多个子进程,如何返回pid和哪个pid?)
答案 0 :(得分:4)
每次调用到fork()
都会创建一个子进程并且只返回单个进程的PID,但没有什么可以阻止您多次调用fork()
来创建多个儿童过程。
不要忘记wait() or waitpid()您的分叉子流程退出,或者您可能会zombie processes闲逛。
答案 1 :(得分:4)
Fork不是Unix 命令,而是syscall Posix手册页中记录的fork(2)。 Linux手册页在这里fork(2) -linux-。
成功时,fork
系统调用返回两次:一次在(调用)父进程中(它给出子进程的pid
),一次在新创建的子进程中(其中)它给0)。否则,这两个进程是克隆(并且一些Linux实现在Linux特定clone(2)系统调用之上实现了fork
并且正在执行具有几乎相同状态的相同程序(实际上两个几乎相同的副本)。这两个(父和子)进程同时运行(作为内核调度的任务,可能在不同的处理器内核上并行运行)。
fork(2)
系统调用可能(很少)失败(例如,为了避免fork bombs),例如当达到RLIMIT_NPROC
与setrlimit(2)系统调用设置的限制时。如果失败,fork
系统调用返回-1,您应该检查errno
。最好检查每个系统调用的失败,fork
不是例外。
Fork是启动进程的常用方法,所有[但极少数例外]用户进程由某些fork
系统调用(或vfork(2)
或clone(2)
之类的变体启动) 。特别是,当您在shell中键入命令(例如ls
或date
)时(例如,/bin/bash
可能在终端模拟器中运行),shell通常是fork
-ing本身,然后execve
- 所需的程序(例外是像cd
这样的shell内置。)
请注意,Linux系统上几乎所有进程都是由fork
创建的。例外是内核启动的过程,如/sbin/init
或/sbin/modprobe
...
您可以多次调用fork
(典型的shell实现会为每个命令执行此操作,除了像cd
之类的内置命令;您可能希望研究像{{{}这样的自由软件shell的源代码1}}或sash
)。您应该最终使用wait(2)或bash
系统调用等待子进程。进程可以使用execve(2)系统调用更改其可执行文件和地址空间。它的address space可以使用mmap(2)和相关的系统调用进行更改。
您可能希望使用waitpid(2)
来了解系统调用的内容,例如:有些贝壳。
我强烈建议您阅读Advanced Unix Programming本书和Advanced Linux programming一本书(后者可以通过免费许可证获得)。
答案 2 :(得分:2)
与其他有争议的答案相同:如果每个进程只能创建一个子进程(仅使用fork()一次),那对进程的沿袭意味着什么?这意味着只有一行,比如init -> login -> shell -> ls
。你想要这样的系统吗?你的结论是什么?