简体   繁体   English

UNIX进程行为

[英]UNIX process behavior

I am trying to understand the following code: 我试图理解以下代码:

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

the output I get looks like this : 我得到的输出看起来像这样:

A  
AC  
AB  
AB  
C 

If I change the first print to printf("A\\n"); 如果我将第一个打印更改为printf("A\\n"); the output is 输出是

A  
C  
A  
B  
B  
C 

How do the processes behave in this situation ? 在这种情况下流程如何表现? I know that the second fork() gets executed in both the parent process and the first child process but why does the output look like this ? 我知道第二个fork()在父进程和第一个子进程中都执行了,但是为什么输出看起来像这样?
Also, why does it print the last 3 letters in that specific order ? 另外,为什么它按该特定顺序打印最后3个字母?

First of all, I believe the result of this sequence is not well defined - it's up to the implementor of printf() and the vagaries of process scheduling. 首先,我认为此序列的结果定义不明确-取决于printf()的实现者和流程调度的变数。

In general, printf() accumulates characters in a buffer, and prints them when it wants to - except that generally the presence of a newline '\\n' triggers immediate printing. 通常,printf()将字符累积在缓冲区中,并在需要时打印它们-除非通常存在换行符'\\ n'触发立即打印。

If the process forks with characters still in the printf() buffer, both the parent and the child process will eventually print those characters. 如果该进程派生的字符仍保留在printf()缓冲区中,则父进程和子进程最终都将打印这些字符。 You fork twice, resulting in 4 processes. 您分叉两次,导致4个过程。 I'll call the original process G(randparent). 我将原始进程称为G(祖父母)。 G creates P(arent) at the first fork. G在第一个分叉处创建P(arent)。 P has pid1 == 0. Next each process forks again. P的pid1 ==0。接下来,每个进程再次派生。 Let's say G creates A(unt) and P creates C(hild). 假设G创建A(unt),P创建C(hild)。 A and C have pid2 == 0. C also has pid1 == 0. A和C的pid2 ==0。C的pid1 == 0。

All of them have either printed the original A\\n, or have A in their printf buffer. 它们全部都打印了原始A \\ n,或者在其printf缓冲区中有A。

Those with pid1 == 0 then printf B\\n. 那些pid1 == 0的人则打印f B \\ n。 If there's still an A in the buffer, it comes out as AB\\n Those with pid2 == 0 then print C\\n 如果缓冲区中还有A,则显示为AB \\ n pid2 == 0的那些,然后输出C \\ n

So the sequence is 所以顺序是

G: A(\n)
P: A(\n)B\n
A: A(\n)C\n
C: A(\n)B\nC\n

The order in which G,P,A, and C run is indeterminate. G,P,A和C的运行顺序不确定。 But the output of any given process appears in the order it's printf()d. 但是任何给定进程的输出均按其printf()d的顺序显示。 It may be interlaced with output from other processes. 它可能与其他进程的输出交错。

If A is printed with \\n, then remove A(\\n) from all the sequences except the grandparent. 如果A上印有\\ n,则从除祖父母之外的所有序列中删除A(\\ n)。

Probable cause of your confusion is that the output of printf("A"); 造成混淆的可能原因是printf("A");的输出printf("A"); is not actually written on the terminal at the moment of the second fork. 在第二个fork时实际上没有写在终端上。 It is in a memory buffer and as such it is duplicated together with the rest of the process. 它在内存缓冲区中,因此将与其余过程一起复制。

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

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