2011-05-15 100 views
6

我想下面的C代码:需要知道叉如何工作?

int main() 
{ 
    printf("text1\n"); 
    fork(); 
    printf("text2\n"); 
    return 0; 
} 

我期待得到的输出从哪里获得两个“text1”中的两个“文本2”,如:

text1 
text1 
text2 
text2 

但是,我是,而是得到:

text1 
text2 
text2 

只有一个“text1”??? 好吧,如果子进程从叉(执行),那么为什么我得到两个“text1”中的以下内容:

int main() 
{ 
    printf("text1"); 
    fork(); 
    printf("text2\n"); 
    return 0; 
} 

输出现在是:

text1text2 
text1text2 

如果子进程后启动叉,输出应该是:

text1 
text2 
text2 
+1

为什么你会期望两个“text1”的副本?只有*一个*过程,直到你碰到'fork'。 – dmckee 2011-05-15 22:20:03

+0

男人叉? (..........) – 2011-05-15 22:20:22

+0

@ user749391:代码按预期工作。像你这样的问题在你真正解释*为什么期望看到两个“text1”之前不能有效回答。 – AnT 2011-05-15 22:24:41

回答

23

fork()通过将当前进程中的所有内容复制到新进程中来创建一个新进程。这通常包括内存中的所有内容以及CPU寄存器的当前值,并进行一些小调整。所以实际上,新进程也会获得进程指令指针的副本,因此它将继续执行原始进程的同一点(fork()后面的指令)。


为了解决您的更新,printf()被缓冲。正常情况下,缓冲区在末尾遇到换行符时被刷新,'\n'。但是,由于您已经省略了这个,所以缓冲区的内容保留并且不会被刷新。最后,这两个进程(原始和子进程)都将有输出缓冲区,其中包含"text1"。当它最终被刷新时,你会在两个进程中看到它。

实际上,您应该始终在分叉之前清空文件和所有缓冲区(包括stdout),以确保不会发生这种情况。

printf("text1"); 
fflush(stdout); 
fork(); 

输出应该是这样的(以某种顺序):

 
text1text2 
text2 
+0

但为什么我得到两个“text1”以下内容: int main() { printf(“text1”); fork(); printf(“text2 \ n”); return 0; } 输出现在是: text1text2 text1text2 如果子进程后叉开始,输出应该是: 文本1 文本2 文本2 – mandavi 2011-05-15 23:01:59

+0

@adi:更新。 – 2011-05-15 23:35:43

+0

thnx很多... !! – mandavi 2011-05-16 00:38:00

2

这是因为fork ED过程fork后开始,而不是从一开始。 exec从入口点开始处理,并打印您所期望的内容。

+0

我仍然不能得到它,因为当我从第一个printf()中删除“\ n”,即时获得“text1”两次,也就是说, int main() { printf(“text1 “); fork(); printf(“text2 \ n”); return 0; } 输出是: text1text2 text1text2 – mandavi 2011-05-15 22:28:58

+3

我想在这种情况下,原始和分叉进程会继承带有“text1”的缓冲输出,因为行尾没有导致缓冲区刷新。我假设如果你在叉子之前在stdout上做了一个flush,你会看到你期望看到的。 – Joe 2011-05-15 22:59:25

6

fork克隆当前进程。新进程将在fork呼叫中“开始”,而不是在main开始时,正如您所期望的那样。因此,当您第一次打印时有1个过程,那么当您分叉时有两个过程。

由于您是fork打印后"text1",它只打印一次。

在第二个例子中,重复输出是由于输出缓冲 - printf实际上并没有向屏幕输出任何内容,直到它被刷新或碰到换行符('\n')。

因此,为了printf第一调用实际上只是写数据到缓冲区某处时,数据然后复制到第二个进程的地址空间,然后printf第二个电话就在两人都刷新缓冲区,完成"text1"缓冲区。

1

子进程将从fork()的位置开始,所以你得到正确的输出。

+0

如你所说,子进程将从fork()开始,我应该得到 text1text2 text2,第二种情况 – mandavi 2011-05-15 23:16:39

7

分叉进程获取变量内存的副本,并且在fork时输出缓冲区尚未刷新。当您分叉时,没有输出写入控制台,只有缓冲。这两个过程因此继续与text1已经在缓冲区,因此都打印它。

+2

@adi,为了得到预期的输出结果,你应该在第一个printf – 2011-05-15 23:37:25

+0

后面加上'fflush(stdout)',谢谢很多....! – mandavi 2011-05-15 23:38:49

0

from man 2 fork:fork将0返回给子进程。

value = fork(); 
if(value == -1) { 
    printf("fork failed\n"); 
    exit(1); 
} 
if(value) { 
    printf("test1\n"); 
} else { 
    printf("test2\n" }; 
} 
1

Problem 1 : the output as 
     text1 
     text2 
     text2

这是因为fork()的创建父进程的精确副本(子)和两个进程的系统调用fork后立即开始他们的执行()。

Problem 2 : the output as 
     text1text2 
     text1text2

这是关于缓冲。请参阅此链接并了解fork()基础知识。 http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html

相关问题