繁体   English   中英

是否需要了解fork的工作原理?

[英]Need to know how fork works?

我正在尝试以下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 

如果子进程在派生之后开始,则输出应为:

text1  
text2  
text2  

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


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

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

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

输出应如下所示(按一定顺序):

text1text2
text2

派生的进程将获取变量存储器的副本,并且在派生时尚未刷新输出缓冲区。 派生时,尚未将任何输出写入控制台,仅将其缓冲。 因此,这两个过程都在缓冲区中已有text1的情况下继续进行,因此都将其打印出来。

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

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

在第二个示例中,重复的输出归因于输出缓冲-printf直到刷新或碰到换行符( '\\n' )时,才向屏幕实际输出任何内容。

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

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

Problem 1 : the output as
      text1
      text2
      text2

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

  问题2:输出为\n       文字1文字2 \n       文字1文字2 

这全部与缓冲有关。 请参考此链接并了解fork()的基础知识。 http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM