UNIX进程行为

时间:2015-01-14 18:40:27

标签: c unix process

我想了解以下代码:

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个字母?

2 个答案:

答案 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");的输出实际上并未在第二个分支时刻写在终端上。它位于内存缓冲区中,因此它与进程的其余部分一起复制。