#include <stdio.h>
main()
{
int i, n=1;
for(i=0;i<n;i++) {
fork();
printf("Hello!");
}
}
如果我把n = 1,我很困惑,它打印Hello 2次。
答案 0 :(得分:1)
fork()
总是能够完美呈现当前流程 - 唯一的区别就是流程ID。
实际上在大多数现代操作系统中,在fork()
之后,两个进程共享完全相同的内存块。操作系统仅在新进程写入该内存时才会生成新副本(在称为“写时复制”的操作模式下) - 如果两个进程都没有更改内存,那么它们可以继续共享该内存块,节省整体系统内存。
但作为一名程序员,所有这一切对你来说都是隐藏的。从概念上讲,你可以把它想象成一个完美的副本。
该副本包含fork()
发生时的所有变量值。因此,如果fork()
在for()
循环内发生i==2
,那么新进程也将在for()
循环的中途进行,i==2
。
但是,这些流程不会分享 i
。当一个流程在i
之后更改fork()
的值时,其他流程的i
不会受到影响。
要了解程序的结果,请修改程序,以便了解哪条进程正在打印每一行,以及它所处的迭代次数。
#include <stdio.h>
# include <sys/types.h>
main() {
int i , n=4;
for(i=0;i<n;i++); {
int pid = getpid();
if(fork() == 0) {
printf("New process forked from %d with i=%d and pid=%d", pid, i, getpid());
}
printf("Hello number %d from pid %d\n", i, getpid());
}
}
由于时间会有所不同,你会得到不同顺序的输出,但是你应该能够理解所有“Hellos”的来源,以及为什么有多少。
答案 1 :(得分:1)
没有单一的“公式”如何完成,因为不同的操作系统以不同的方式完成它。但是fork()
做的是它复制了这个过程。通常涉及的粗略步骤:
答案 2 :(得分:1)
你不只是分叉'主'过程,你也分叉孩子们! 第一次迭代:
m -> c1
//then
m -> c2 c1-> c1.1
m -> c3 c1-> c1.1 c2->c2.1 c1.1 -> c1.1.1
表示i = ....
以这种方式写下来:
main
fork
child(1)
fork child(2)
fork child(1.1)
fork child(3)
fork child(1.2)
fork child(2.1)
依旧......
答案 3 :(得分:0)
当你fork()时,你创建一个新的子进程,它有不同的虚拟内存,但最初显示在与父亲相同的物理内存中。此时,两个进程只能从内存中读取数据。如果他们想要在该公共内存中编写或更改任何内容,则他们使用不同的物理内存并对该内存具有写入属性。因此,当你fork()时,你的孩子最初具有与其父亲相同的i值,但该值对于每个孩子都是单独改变的。
答案 4 :(得分:0)
是的,有一个公式:
fork()
只生成一个几乎相同的流程副本。然而,它返回两次。一旦进入原始进程(父进程,返回子进程pid)和进入子进程一次(返回0)。