Подтвердить что ты не робот

Кто выполняет сначала после fork(): родительский или дочерний?

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

  #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   

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

Ответ 4

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