将创建多少个进程和线程?

8
我有这段代码,想要理解它会创建多少进程和线程:

我有这样一段代码,想要理解它将创建多少个进程和线程:

pid t pid; 
pid = fork(); 
if (pid == 0) { /* child process */ 
 fork(); 
 thread create( . . .); 
} 
fork(); 

我认为它从if循环中的fork创建了2个线程,并且创建了8个进程?但我不确定是否正确。


3
没有循环。那是一个“如果”。 - QuentinUK
为什么要8个进程?其中一个 fork 调用在 if 测试中。 - didierc
4个回答

18

实际上,应该有8个线程和6个进程。

这里是图示以便更加清晰明了:

1) after first fork():

   |-------------------  child of p0 [p1]
---|-------------------  parent      [p0]

2) after second fork():

       |---------------  child of p1 [p2]
   |---|---------------              [p1]
---|-------------------              [p0]

3) after pthread_create():

            -----------  thread 1 of p2 [p2t1] 
       |---/-----------  thread 0 of p2 [p2t0]
       |    -----------  thread 1 of p1 [p1t1]
   |---|---/-----------  thread 0 of p1 [p1t0]
---|-------------------                 [p0]

4) after third fork():

         |------------ child of p2 [p5]
         |      ------             [p2t1]
       |-|-----/------             [p2t0]
       |   |---------- child of p1 [p4]
       |   |    ------             [p1t1]
   |---|---|---/------             [p1t0]
   |     |------------ child of p0 [p3]
---|-----|------------             [p0]

重要提示:请记住,fork(2)调用仅克隆执行它的线程,因此进程4[p4]只有一个线程(对进程5[p5]同样适用)。


1
这个问题来自(据我所知)《操作系统概念第九版》,该书在第183页指出,如果“分离的进程在分叉后没有调用exec(),则分离的进程应该复制所有线程。”这意味着将有10个线程。这是否不准确?它还指出:“一些UNIX系统选择拥有两个版本的fork(),一个是复制所有线程的版本,另一个是仅复制调用fork()系统调用的线程的版本。” - Sammaron
@Sammaron:请参考此手册 - jxh
4
pthread_create后,为什么p1和p2下会有两个线程? - renga_in_stack

11
每次调用 fork 时都会创建一个额外的进程。
第一次调用 fork 时,父进程 P 创建子进程 SP1。 在 fork 后,父进程再次调用 fork(跳过 if 语句),创建子进程 SP2。
SP1 调用 fork 并创建子子进程 SSP1。 然后,SP1 创建一个线程。 SP1 离开 if 语句并再次调用 fork,创建子子进程 SSP2。
SSP1 创建一个线程。 SSP1 离开 if 语句并调用 fork,创建子子子进程 SSSP。
因此,共创建了 5 个进程:SP1、SP2、SSP1、SSP2、SSSP。如果算上原始进程 P,则有 6 个进程。
只有 SP1 和 SSP1 创建了线程,所以总共创建了 2 个线程。如果计算所有进程的主线程,则有 7 或 8 个线程,具体取决于是否计算原始进程 P。
以下是进程和线程被创建的示意图,与代码相关。
                         P
pid t pid;               |
pid = fork();            +------SP1
if (pid == 0) {          |      |
 fork();                 |      +---------------SSP1
 thread create(...);     |      |-SP1's thread  |-SSP1's thread
}                        |      |               |
fork();                  +-SP2  +-SSP2          +-SSSP
                         | |    | |             | |

3

它不应该是2个线程和6个进程吗?

M
|  ↘
M     A
|     |↘
M     A*   B*
|     |    |
| ↘   | ↘  |↘
M   C A  D B  E

我使用 * 代表线程。


0

总分叉进程数=5 线程创建数=2


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接