c中的fork()系统调用 #包括 #包括 int main() { fork(); fork()&&fork()| fork(); fork(); printf(“分叉的”); 返回0; }
这会导致理解如何计算执行程序后生成的进程数的困难? 帮我弄清楚 平台——UBUNTU 10.04您不应该像这样使用fork()。从未。然而,在现实生活中你不需要这样做。 如何使用它:c中的fork()系统调用 #包括 #包括 int main() { fork(); fork()&&fork()| fork(); fork(); printf(“分叉的”); 返回0; },c,unix,fork,C,Unix,Fork,这会导致理解如何计算执行程序后生成的进程数的困难? 帮我弄清楚 平台——UBUNTU 10.04您不应该像这样使用fork()。从未。然而,在现实生活中你不需要这样做。 如何使用它: #include <stdio.h> #include <unistd.h> int main() { fork(); fork() && fork() || fork(); fork();
#include <stdio.h>
#include <unistd.h>
int main()
{
fork();
fork() && fork() || fork();
fork();
printf("forked\n");
return 0;
}
intmain(){
/*代码*/
pid_t pid=fork();
if(pid<0){
/*错误,未生成子进程*/
}
如果(pid>0){
/*我们是父进程,pid是生成的一个子进程的进程ID*/
}
/*否则,我们就是子进程,在父进程中调用fork()之后只运行一个命令*/
/*还有代码吗*/
返回0;
}
将文件保存为fork count.c
。然后用gcc fork count.c-o fork count编译它。然后可以运行它并使用/fork count | wc-l
计算输出行数
int main() {
/* code */
pid_t pid = fork();
if (pid < 0) {
/* error, no child process spawned */
}
if (pid > 0) {
/* we are the parent process, pid is the process ID of the ONE child process spawned */
}
/* else, we are the child process, running exactly one command later the fork() was called in the parent. */
/* some more code */
return 0;
}
fork
系统调用返回一个整数:父进程中进程的PID和子进程中的0。如果发生错误,则不创建任何进程,并返回-1
|
和&&
是逻辑运算符
如果在计算左操作数后知道运算符的结果,则要求运算符短路(即不计算右操作数):
- 对于
运算符,如果其左操作数为!=0|
- 对于
运算符,如果其左操作数为==0,则不计算其右操作数&&
&&
的计算结果为true,因此它们不会在此行中再次分叉。对于p3、p4、p5、p6,和&
的计算结果为false,因此它们会分叉
在这里,生成四个新进程,总共得到6+4=10
fork()
10个过程中的每一个都再次分叉,得到20个。我找到了这个问题的正确解释: fork()系统调用将进程作为正在增长的二叉树的叶子生成。如果我们调用fork()两次,它将生成22=4个进程。这4个过程构成了二叉树的叶子树。一般来说,如果我们是级别l,并且fork()被无条件调用,那么级别(l+1)将有2l个进程。它相当于二叉树中(l+1)级的最大子节点数 作为另一个例子,假设我们已经无条件地调用了fork()调用3次。我们可以使用三个级别的完整二叉树来表示生成的进程。在第3级,我们将有23=8个子节点,对应于运行的进程数 关于C/C++逻辑运算符的说明: 逻辑运算符&&的优先级高于| |,并且具有从左到右的关联性。执行左操作数后,将估计最终结果,右操作数的执行取决于左操作数的结果以及操作类型 在AND(&&)的情况下,对左操作数求值后,仅当左操作数求值为非零时,才会对右操作数求值。在OR(| |)的情况下,在计算左操作数后,仅当左操作数的计算结果为零时,才会计算右操作数 fork()的返回值: fork()的手册页引用了以下关于返回值的摘录 成功时,在父进程中返回子进程的PID,在子进程中返回0。失败时,在父进程中返回-1,不创建子进程,并正确设置errno PID类似于进程句柄,用无符号int表示。我们可以得出结论,fork()将在父级中返回非零,在子级中返回零。让我们分析一下程序。为了便于记法,请按如下所示标记每个fork()
|| fork();
#包括
int main()
{
fork();/*A*/
(fork()/*B*/&&
fork()/*C*/)| |/*B和C根据优先级分组*/
fork();/*D*/
fork();/*E*/
printf(“分叉的”);
返回0;
}
前两个fork()调用是无条件调用的
在0级,我们只有主进程。main(图中的m)将创建子C1,两者都将继续执行。孩子们按照他们创造的顺序被编号
在第1级,我们运行m和C1,并准备执行fork()–B(注意,B、C和D被命名为&&和| |运算符的操作数)。初始表达式B将在此级别运行的每个子进程和父进程中执行
在第2级,由于fork()–B由m和C1执行,我们将m和C1作为父级,将C2和C3作为子级
fork()–B的返回值在父级中不为零,在子级中为零。由于第一个运算符是&,由于返回值为零,子C2和C3将不会执行下一个表达式(fork()-C)。父进程m和C1将继续使用fork()–C。子进程C2和C3将直接执行fork()–D,以评估逻辑OR运算的值
在3级,我们将m、C1、C2、C3作为运行进程,将C4、C5作为子进程。表达式现在简化为((B&&C)| | D),此时(B&&C)的值是显而易见的。在父母中它是非零的,在孩子中它是零的。因此,知道总体B&C|D结果的父母将跳过fork()–D的执行。因为,在评估为z的儿童(B&C)中
&& fork()
|| fork();
#include <stdio.h>
int main()
{
fork(); /* A */
( fork() /* B */ &&
fork() /* C */ ) || /* B and C are grouped according to precedence */
fork(); /* D */
fork(); /* E */
printf("forked\n");
return 0;
}