简体   繁体   English

谁在fork()之后首先执行:父或子?

[英]Who executes first after fork(): parent or the child?

I know that it can be either of these. 我知道它可以是其中之一。 But I always see that the child executes first on my UNIX terminal. 但我总是看到孩子在我的UNIX终端上首先执行。 Also, why don't the parent and child execute in parallel. 此外,为什么父和子并行执行。 They seem to be executing serially. 他们似乎在连续执行。 Is this because they share the same terminal? 这是因为他们共用同一个终端吗?

In general, nothing can be said about the relative order of their execution. 一般而言,关于其执行的相对顺序,没有任何说法。

Now, let's consider your specific problem. 现在,让我们考虑一下您的具体问题。 If: 如果:

  1. both processes take a non-trivial amount of time to run, and 这两个过程都需要花费大量的时间来运行,并且
  2. you're saying that one runs to completion before the other makes any progress, and 你说的是在对方取得任何进展之前完成一个完成,并且
  3. there are unused CPU cycles, and 有未使用的CPU周期,和
  4. this happens every time you run the application. 每次运行应用程序时都会发生这种情况。

Most likely this indicates that there is some (perhaps unintended) synchronization going on between the two processes. 很可能这表明在两个进程之间存在一些(可能是无意的)同步。

Actually that is the intended behavior, even if it is not currently functioning as it should, meaning that the parent can run before the child and the child can run before the parent. 实际上这是预期的行为,即使它当前没有正常运行,这意味着父项可以在子项之前运行,而子项可以在父项之前运行。

The goal is to run the child process first. 目标是首先运行子进程。

In short, the logic behind it is that if the child is ran first, the overhead of copy on write (COW) is eliminated if the child is calling exec since the parent does not have any chance to write to the address space. 简而言之,它背后的逻辑是,如果孩子先被运行,如果孩子正在调用exec则写入时复制的开销(COW)将被消除,因为父母没有任何机会写入地址空间。

If you are calling vfork then almost all implementations define that the child will run first and then parent will execute.(Untill child calls exec).So you will notice serial execution in case of vfork irrespective of schedular.However when a fork is called simply two new processes are created.They are free to run independently.(Just like any other process). 如果你正在调用vfork,那么几乎所有的实现都会定义子进程会先运行然后父运行。(直到子进程调用exec)。所以你会注意到vfork的串行执行而不管schedulelar.However只是调用fork时创建了两个新进程。它们可以独立运行。(就像任何其他进程一样)。 Which process runs first will be heavily dependent on the scheduling algorithm. 首先运行哪个进程将严重依赖于调度算法。 Beside scheduling algorithm the number of processes running at that time will also determine the nature of output.Moreover if you are using standard library i/o functions they output data in bursts(probably not the right word). 除了调度算法之外,此时运行的进程数也将决定输出的性质。另外,如果使用标准库i / o函数,它们会以突发形式输出数据(可能不是正确的单词)。 That will also determine to some extent who gets to write first. 这也将在某种程度上决定谁先写。 Here is a sample code(That doesn't make much sense practically but still a good example that parent and child indeed run in synchronism 这是一个示例代码(实际上这没有多大意义,但仍然是父母和孩子确实同步运行的一个很好的例子

  #include<stdio.h>
  #include<string.h>
  static void charAtTime(char buff[])
{
char *p=buff;
while(*p) {
putc(*p,stdout);
(p++);
}

}
    int main()
{
setbuf(stdout,NULL);   //set output stream to be unbuffered.Now each process will try to throw chars as soon as they are ready
int pid;
char buff[1000];
if((pid=fork())<0)   //First fork
    {
    fprintf(stderr,"Fork error\n");
    }
else if(pid==0)
    {
    strcpy(buff,"i am the child.I love beyblade.I love anime.I love pokemon\n");
   charAtTime(buff);    
  }
   else {
     int pid2=fork();   //secnd fork
     if(pid2==0){
     strcpy(buff,"I am the younger child\n");
         charAtTime(buff);
        }
   else {
int pid3;
pid3=fork();    //third fork
if(pid3==0)
    {
    strcpy(buff,"I am from the 2nd generation\n");
    charAtTime(buff);
    }
     else {
    strcpy(buff,"Our family tree is bit confusing\n");
    charAtTime(buff);
    }
        }

     strcpy(buff,"I am the big daddy of them.I have the right before them\n");
    }

   return 0;
    }

For my system the following output comes 对于我的系统,以下输出来了

   i am thOeI u ra cmfha mtihley  yoIturne geea rmi  cshf irblodimt
   thceo i2nnlfdd .uIg elnseoivrnea gb
   teiyobnl
   ade.I love anime.I love pokemon   

However if reduce the number of forks to two(Only two processes competing) then the output is less ugly.Its the parent which executes first.(Probably because its current running process when the other process is created) 但是,如果将fork的数量减少到两个(只有两个进程竞争),那么输出就不那么难看。它是先执行的父进程。(可能是因为当创建另一个进程时它的当前运行进程)

There is not really one executing before the other. 没有一个在另一个之前执行。 It is simply that the parent will fork() then wait() for the child to complete. 只是父将fork()然后wait()让孩子完成。 It may even fork several times if you use a piped series of commands for instance. 如果您使用管道系列命令,它甚至可能会分叉几次。

As the other answers, you may not know it, and you should not depend on it. 正如其他答案,你可能不知道它,你不应该依赖它。

But historically on Linux, parent contiune to execute, and after this the children. 但历史上在Linux上,父母继续执行,并在此之后的孩子们。 On a old Linux Kernel, it was implemented the contrary way: quickly executing the children, which probably will call an exec . 在旧的Linux内核上,它以相反的方式实现:快速执行子进程,这可能会调用exec In this manner there will be no copy on write memory (which should be done at every write of parent). 以这种方式,写入存储器上将没有副本(应该在每次写入父节点时完成)。 Guess what? 你猜怎么了? That changes broke many tools in subtle way (and difficult to debug), so it was reverted. 这种变化以微妙的方式打破了许多工具(并且难以调试),因此它被还原了。 A lost of optimization!. 失去了优化!

So do not relay on which process will be execute first. 所以不要中继首先执行哪个进程。

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

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