Может ли ЦП удерживать процесс в состоянии ожидания в течение 10 секунд, пока выполняется дочерний процесс?

Этот вопрос был частью моих экзаменов в середине семестра, и ответ на него, данный профессором, совершенно абсурден.

Я просто хочу знать, какой правильный ответ.

КОД:

#include<unistd.h>

  // Other Libraries  


void ChildProc()  
{  
  sleep(10);
  printf("Child Process\n");
}

void ParentProc()
{  
  printf("Parent Process");
}  

int main()  
{  
  pid_t pid;  
  pid = fork();  

  if(pid==0)  
    ChildProc();  
  else  
    ParentProc();  

  return 0;  
}

ВОПРОС: Каковы все возможные результаты следующего кода?

Мои ответы были,

1)
РЕЗУЛЬТАТ: None
ПРИЧИНА: При сбое ветвления. (Система не разрешает создание дочернего процесса)

2)
ВЫВОД: Parent Process
ПРИЧИНА: Поскольку и родитель, и дочерний элемент теперь находятся в состоянии гонки. Кто бы ни мог выполниться первым, родитель завершит работу раньше и, таким образом, выйдет из функции, а затем завершится сама программа. Теперь ребенок не может остаться в живых, когда родитель закончился. Так оно и заканчивается.

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

ВЫВОД:
Child Process
Parent Process

Хотя вероятность этого очень-очень-очень редка, и только когда переключатель контекста процесса очень занят, но все же он говорит, что это возможно? Теперь я не убежден в его рассуждениях, и что знать, действительно ли это возможно, по крайней мере, в современных ОС Linux ??


person Pinkesh Badjatiya    schedule 10.09.2015    source источник


Ответы (4)


Теоретически ВОЗМОЖНО, что родительский процесс заблокирован на 10 секунд [не процессором как таковым, а механизмом планирования ОС]. Но поскольку в этом случае разветвленный процесс имеет тот же приоритет, что и родительский, маловероятно, что дочерний процесс запустится до завершения родительского, но, как и для любых двух несинхронизированных процессов, невозможно полностью гарантировать, в каком порядке они выполняются.

Конечно, на моей машине дочерний процесс не запускается до тех пор, пока родительский процесс не завершится. Итак, вывод:

Parent process 
[my prompt $] Child Process

Каждый раз. Но нет стопроцентной гарантии, что так и будет.

person Mats Petersson    schedule 10.09.2015
comment
У меня аналогичное мнение, но то, что процесс остается в заблокированном состоянии 10сек до исполнения, практически невозможно. Мой аргумент в том, что теоретически это возможно, но практически невозможно. - person Pinkesh Badjatiya; 12.09.2015
comment
Согласованный. Для этого потребуются довольно экстраординарные обстоятельства. Что-то вроде запуска другого процесса, который имеет НАМНОГО более высокий приоритет в тот момент, когда запускается дочерний процесс. Но даже в этом случае изменение порядка маловероятно. - person Mats Petersson; 13.09.2015
comment
согласен абсолютно, но вопрос ЭТО ВОЗМОЖНО? - person Pinkesh Badjatiya; 15.09.2015
comment
Да, и это так. На самом деле, я видел ситуации, когда Linux делает действительно странные вещи с синхронизацией процесса, если данные выгружаются на диск. Переключение между одним приложением и другим может занять полминуты. Таким образом, в этой ситуации МОЖЕТ случиться, что процесс удерживается в течение 10 или более секунд. - person Mats Petersson; 15.09.2015

Обратитесь к другому вопросу из '11:

понимание fork(), sleep() и потока процессов

Родительский процесс должен использовать wait(), иначе я считаю, что он будет показывать только:

Родительский процесс

Дочерний процесс

(или не разветвляться)

person Willdorf    schedule 10.09.2015
comment
Вызов ожидания заставляет родителя явно ждать выполнения дочернего, а до тех пор он просто ждет буквально. Это исправляет приведенный выше код. Скорее мы должны найти вывод этого неправильного кода. :П - person Pinkesh Badjatiya; 10.09.2015

Мы не можем предсказать, какой процесс запустится первым, но да, если процесс находится в состоянии сна, другой процесс получает квант времени процессора.

O/P: родительский процесс, дочерний процесс

person Rohan Nagalkar    schedule 10.09.2015

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

Примечание:

когда я запускаю ваш код, он сначала запускает родительский (распечатывает родительский процесс), возвращает мою консоль, затем запускает дочерний (распечатывает «дочерний процесс»), а затем переходит в непрерывное ожидание :)

когда я помещаю printf("основной процесс") в конец main() перед возвратом 0; он печатает в следующем порядке: родительский процесс, основной процесс, возвращение в консоль (сон), дочерний процесс, основной процесс. Ясно одно, что родитель не будет ждать потомка, и не обязательно, чтобы потомок всегда получал процессор раньше родителя.

ВОПРОС: почему программа переходит в режим непрерывного ожидания и почему операторы, находящиеся за пределами родительского и дочернего процессов, выполняются два раза

person incompetent    schedule 11.09.2015
comment
кстати, он довольно хорошо знает о ядре, очищая мои концепции с первого дня. Ваша причина вряд ли произойдет. - person Pinkesh Badjatiya; 12.09.2015
comment
о, я не хотел сказать, что он не знает, я пытаюсь подчеркнуть, что если вы правильно сформулировали то, что он сказал, то он может быть прав для старых машин, а не для современных, я пытаюсь перефразировать свой ответ - person incompetent; 13.09.2015
comment
Что касается последнего вопроса, который вы задали, я не уверен, каков ваш фактический вопрос. Но, по моему мнению, вы хотите знать, почему глобальные инициализации выполняются дважды. На самом деле глобальные переменные инициализируются только один раз, и когда дочерний элемент разветвляется, переменные копируются (на самом деле дочерний элемент имеет общую память с родителем, пока он что-то не напишет, известный как политика копирования при записи). - person Pinkesh Badjatiya; 15.09.2015