2016-03-25 3 views
4

Я пытаюсь работать с несколькими процессами в Linux с использованием fork() функции в C, это мой код:родительского процесса Идентификатор дочернего процесса отличается от PID родительского

p1 = fork(); 

if(p1 != 0){ 
    p2 = fork(); 
} 

printf("My PID is %d\n",getpid()); 
printf("My parent PID is %d\n",getppid()); 

Теперь давайте предположим, что родительский процесс ID 100, и два дочерних процессов (p1, p2) идентификаторы 101 & 102, и процесс инициализации PID будет 0 мой ожидается выход:

My PID is 100 
My parent PID is 0 

My PID is 101 
My parent PID is 100 

My PID is 102 
My parent PID is 100 

Вместо я вижу что-то другое, два дочерних процессов имеют тот же PPID, но первый процесс ha с другой PID. Вот пример вывода я получил:

My PID is 3383 
My parent PID is 3381 

My PID is 3387 
My parent PID is 1508 

My PID is 3386 
My parent PID is 1508 

Мой вопрос, не должен родительский PID двух дочерних процессов будет ? Надеюсь, кто-то может объяснить, как все это работает и что я делаю (или думаю) неправильно.

+3

Что происходит, если вы добавляете спящий режим после выполнения обоих 'printf'? –

+0

@MohitJain это действительно исправлено, как это происходит? Я имею в виду сон. После того, как 'printf' ничего не изменит, поскольку процессы будут созданы, а' fork' - то же самое ... – argamanza

ответ

5

[Подтвержденные из комментариев]

Ваш выход синхронизации зависит. Если родительский процесс завершится после процесса детей, ваш результат будет таким, как ожидалось.

Если родительский процесс заканчивается перед процессом детей, вывод может быть неожиданным (до того, как родитель больше не существует, родительский идентификатор будет другим). Когда родительский процесс умирает (заканчивается), init или какой-либо другой процесс определения (1508 в вашем случае), становится новым родителем дочернего элемента (ren). Такие дети называются сиротскими процессами.

Согласно странице exit человека от Single UNIX Specification, версия 2:

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

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

+1

Имеет смысл, но все же '1508' - странный PID для' init'. – alk

+0

@alk Это не обязательность init. pid init - 1. На самом деле ppid сироты задается идентификатором процесса, определенным для реализации. –

+0

«Реализация, определенная *» с точки зрения того, что ОС? Здесь Linux. Кажется, я чего-то не хватает. – alk

1

Там нет ничего плохого с кодом

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

try puttin wait(); для родителя, чтобы завершить выполнение всех дочерних процессов.

Смежные вопросы