[英]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
问题2:输出为\n 文字1文字2 \n 文字1文字2
子进程将从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.