我想了解以下代码:
int main(int argc, char **argv)
{
int pid1,pid2;
if((pid1=fork())<0)
{
printf("Error bla bla");exit(1);
}
else printf("A");
if((pid2=fork())<0)
{
printf("Error bla bla");exit(2);
}
if(pid1==0)printf("B\n");
if(pid2==0)printf("C\n");
exit(0);
return 0;
}
我得到的输出看起来像这样:
A
AC
AB
AB
C
如果我将第一次打印更改为printf("A\n");
,则输出为
A
C
A
B
B
C
在这种情况下,流程如何表现?我知道第二个fork()
会在父进程和第一个子进程中执行,但为什么输出看起来像这样?
另外,为什么要按特定顺序打印最后3个字母?
答案 0 :(得分:1)
首先,我认为这个序列的结果没有很好地定义 - 这取决于printf()的实现者和流程调度的变幻莫测。
通常,printf()在缓冲区中累积字符,并在需要时打印它们 - 除了通常存在换行符'\ n'触发立即打印。
如果进程中的字符仍然在printf()缓冲区中,则父进程和子进程最终将打印这些字符。你分叉两次,产生4个进程。我将调用原始进程G(randparent)。 G在第一个分叉处创建P(arent)。 P有pid1 == 0.然后每个进程再次分叉。假设G创建A(非),P创建C(hild)。 A和C有pid2 == 0.C也有pid1 == 0.
所有这些都打印了原始的A \ n,或者在printf缓冲区中有A。
那些pid1 == 0然后printf B \ n。如果缓冲区中仍有A,则表示为AB \ n 那些pid2 == 0然后打印C \ n
所以序列是
G: A(\n)
P: A(\n)B\n
A: A(\n)C\n
C: A(\n)B\nC\n
G,P,A和C的运行顺序是不确定的。但是任何给定进程的输出都按照printf()d的顺序出现。它可以与其他进程的输出交织。
如果用\ n打印A,则从除祖父母之外的所有序列中删除A(\ n)。
答案 1 :(得分:0)
可能导致混淆的原因是printf("A");
的输出实际上并未在第二个分支时刻写在终端上。它位于内存缓冲区中,因此它与进程的其余部分一起复制。