需要知道fork如何工作?

我正在尝试以下C代码:

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

我期待得到输出,我得到两个“text1”和两个“text2”,如:

 text1 text1 text2 text2 

但是,相反,我得到:

 text1 text2 text2 

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

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

现在的输出是:

 text1text2 text1text2 

如果子进程在fork之后启动,则输出应为:

 text1 text2 text2 

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


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

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

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

输出应该如下所示(按某种顺序):

 text1text2
文本2

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

fork克隆当前进程。 新进程将在fork调用时“启动”,而不是像您期望的那样在main的开头。 因此,当您第一次打印时有1个进程,那么当您进行分叉时有两个进程。

由于您在打印"text1"后进行fork ,因此只打印一次。

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

因此,第一次调用printf实际上只是将数据写入某个缓冲区,然后将数据复制到第二个进程的地址空间,然后第二次调用printf将刷新缓冲区,并在两个缓冲区中都"text1"

这是因为fork ed进程在fork之后开始,而不是从一开始就开始。 exec从入口点开始处理并打印出您期望的内容。

子进程将从fork()的位置开始,因此您将获得正确的输出。

 问题1:输出为
      文本1
      文本2
      文本2 

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

 问题2:输出为
       text1text2 
       text1text2 

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

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" }; }