Что именно происходит с fork ()? - PullRequest
3 голосов
/ 21 февраля 2012
int main(){

    char ch;

    fork();

    cin >> c;
}

После вызова fork () у меня должно быть 2 точных процесса, выполняющих один и тот же код. Почему после запуска этого простого примера меня либо попросили ввести символ только один раз, либо дважды? Разве система не должна ожидать 2 входа каждый раз, когда я запускаю эту программу?

>./a.out 
a
>./a.out
a
b
>

Ответы [ 4 ]

6 голосов
/ 21 февраля 2012

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

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

Не следует ожидать согласованного поведения, если два процесса читают с одного терминала.

2 голосов
/ 21 февраля 2012

Когда вызывается fork (), операционная система обычно копирует все пространство памяти исполняемой программы (вроде). Затем обе программы запускаются. Единственное отличие состоит в том, что в «новом» процессе fork () возвращает 0, а в «старом» процессе возвращает идентификатор процесса нового процесса.

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

1 голос
/ 21 февраля 2012

fork () создает дочерний процесс.

Но какой процесс (среди родительского и новорожденного ребенка) получает срез ЦП, не определено.Когда оба процесса заблокированы для ввода с клавиатуры, дочерний или родительский может получить ввод.Если родитель получает токен, он считывает входные данные в свою переменную, определенную в его адресном пространстве, и завершает работу.И ребенок никогда не получит шанс прочитать из ввода.И этот потерянный дочерний процесс будет затем принят корневым процессом (pid = 1).См. ps output.

И в другом случае, когда дочерний элемент получает токен, читает данные и выходит, родительский элемент все еще жив и, следовательно, блокирует для ввода снова.

0 голосов
/ 21 февраля 2012

Включите wait () после fork () и попробуйте.

...