当孩子们叉子时fork()如何工作?

时间:2011-09-30 11:13:54

标签: c unix fork wait

我已经执行了一段代码。它如下所示:

#include<stdio.h>

main() {
int i=0;
fork();
printf("The value of i is:%d\n",++i);
fork();
printf("The value of j is:%d\n",++i);
fork();
wait();
}

我得到了以下输出:

The value of i is:1
The value of j is:2
The value of i is:1
The value of j is:2
The value of j is:2
pckoders@ubuntu:~$ The value of j is:2

有人可以向我解释fork()和wait()函数在这里扮演什么角色?

4 个答案:

答案 0 :(得分:11)

fork()来电是字面上的分叉。完成后,您将拥有2个具有精确堆栈的精确进程,并且所有描述符都指向相同的对象。您可以通过返回值区分它们。对于子进程fork(),返回0,表示父 - 子进程ID。

所以

main() {
int i=0;
fork(); 
// at this point you are having 2 processes. stdout and stdin are basically just dupplicates.
//          (P)
//        /     \
//     (P)       (C)
//   prints1    prints 1
printf("The value of i is:%d\n",++i); // so 2 processes with print 1
fork();
// now you are having 4 processes( both parent and children forked)
//                   (P)
//                 /     \
//               /         \
//           (P)            (C)
//         /     \         /   \
//      (PP)     (PC)    (CP)  (CC)
//   prints 2  prints 2  prints 2  prints 2
printf("The value of j is:%d\n",++i);
fork();
// now 4 processes are forking. now you have 8 processes
//                                   (P)
//                                /       \
//                            /              \
//                         /                    \
//                   (P)                           (C)             
//                 /     \                       /     \           
//               /         \                   /         \          
//          (PP)           (PC)             (CP)          (CC) 
//         /     \        /     \          /    \       /     \        
//     (PPP)    (PPC)  (PCP)   (PCC)   (CPP)   (CPC)  (CCP)  (CCC)   

wait();
}

答案 1 :(得分:6)

程序生成一个进程树。在每fork,这棵树分成两部分。如果你拿一张纸,画这棵树并不是很难;唯一困难的是由于您使用前缀i而使++值正确。如果您在结束时让每个进程sleep持续几秒钟,您还可以使用pstree程序观察树。

然后,每个进程都运行wait系统调用,waits for any one of its child processes(进程树中的子节点)完成。

答案 2 :(得分:1)

在第一个fork()之后有两个进程(当前和它的精确副本,子进程),它们都打印了1个。

这两个进程中的每一个都与第二个fork()调用重复,并且有4个进程,每个进程打印2个。

它们的输出是随机顺序的,因为它始终与并行执行有关。

答案 3 :(得分:-1)

Forking进程以树状方式创建Children。将每个fork作为二叉树的不同层。当你不发出fork()时,你有一个只有一个根节点的进程树。当你发出问题时一个fork()然后你有一个二元树现在有两个级别,第一个级别将包含父进程,第二个级别将包含两个进程 - 父进程和子进程。

当你想要找出你手边的进程数时,只需继续构建二进制/进程树并查看最后一级有多少个节点,最后一个级别只是进程的当前状态/ tree.Wait函数让你的父进程等待子进程完成执行。在你不想要僵尸进程的应用程序中你需要发出一个等待,否则这些僵尸进程将继续占用系统...... link

请记住,当您始终希望父级在子级之后完成时,等待也很有用。分叉并不总是给出相同的输出,顺序是混乱的,因此总是得到相同的输出,使用wait()。要等待特定的子进程,请使用wait(pid),其中pid是特定子进程的pid,并且可以通过子进程空间内的getpid获取该pid。