Кто первым выполняет после fork (): родитель или потомок? - PullRequest
21 голосов
/ 13 декабря 2011

Я знаю, что это может быть любой из них. Но я всегда вижу, что дочерний процесс выполняется первым на моем терминале UNIX. Кроме того, почему родитель и потомок не выполняются параллельно. Кажется, они выполняются поочередно. Это потому, что они используют один и тот же терминал?

Ответы [ 5 ]

21 голосов
/ 13 декабря 2011

В общем, ничего не скажешь об относительном порядке их исполнения.

Теперь давайте рассмотрим вашу конкретную проблему. Если:

  1. оба процесса занимают нетривиальное время, а
  2. вы говорите, что один завершается до того, как другой достигнет любого прогресса и
  3. есть неиспользуемые циклы процессора, а
  4. это происходит каждый раз, когда вы запускаете приложение.

Скорее всего, это указывает на то, что между этими двумя процессами происходит некоторая (возможно, непреднамеренная) синхронизация.

6 голосов
/ 13 декабря 2011

На самом деле это предполагаемое поведение, даже если оно в настоящее время не функционирует должным образом, что означает, что родитель может работать раньше, чем ребенок, а ребенок - раньше, чем родитель.

Цель - запуститьдочерний процесс первым.

Короче говоря, логика заключается в том, что если дочерний элемент запускается первым, накладные расходы на копирование при записи (COW) устраняются, если дочерний элемент вызывает exec, так как родитель не имеет никакой возможностинаписать в адресное пространство.

3 голосов
/ 14 декабря 2011

Если вы вызываете vfork, то почти во всех реализациях определяется, что сначала будет выполняться дочерний элемент, а затем будет выполняться родительский (до тех пор, пока дочерний вызов не вызывает exec). Так что вы заметите последовательное выполнение в случае vfork независимо от schedular.называется просто два новых процесса создаются. Они могут свободно работать независимо. (Как и любой другой процесс).Какой процесс будет запущен первым, будет сильно зависеть от алгоритма планирования.Помимо алгоритма планирования, число процессов, запущенных в это время, также будет определять характер вывода. Более того, если вы используете стандартные функции ввода-вывода библиотеки, они выводят данные в пакетах (вероятно, не то слово).Это также определит, в какой степени, кто будет писать первым.Вот пример кода (Это не имеет особого смысла практически, но все же хороший пример того, что родитель и потомок действительно работают синхронно

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

Для моей системы выводится следующий вывод

   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   

Однако, если уменьшить число вилок до двух (конкурируют только два процесса), то вывод будет менее уродливым. Это родитель, который выполняется первым. (Возможно, потому что его текущий запущенный процесс создается другим процессом).)

1 голос
/ 13 декабря 2011

На самом деле не один исполняется раньше другого. Это просто, что родитель будет fork() затем wait() для ребенка, чтобы закончить. Например, он может даже разветвляться несколько раз, если вы используете ряд команд по конвейеру.

0 голосов
/ 25 марта 2019

Как и другие ответы, вы можете не знать об этом, и вы не должны зависеть от этого.

Но исторически в Linux продолжаются выполнение родительского элемента, а после этого дочерние элементы.В старом ядре Linux это было реализовано наоборот: быстрое выполнение дочерних процессов, которое, вероятно, будет называться exec.Таким образом, не будет копии в памяти записи (что должно быть сделано при каждой записи родительского элемента).Угадай, что?Эти изменения незаметно сломали многие инструменты (и их было трудно отладить), поэтому они были отменены.Потеря оптимизации!.

Так что не передавайте, какой процесс будет выполняться первым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...