2016-03-25 7 views
4

Ich versuche, mit mehreren Prozessen in Linux arbeiten mit fork() Funktion in C, das ist mein Code:Prozess Eltern ID des Kind-Prozess von PID der Eltern unterscheidet

p1 = fork(); 

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

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

Nun wollen wir den übergeordneten Prozess übernehmen ID 100 ist, und die beiden untergeordneten Prozessen (P1, P2) IDs sind 101 & 102 und der init-Prozess PID wird 0 meine erwartete Ausgabe ist:

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 

Stattdessen sehe ich etwas anderes, die beiden untergeordneten Prozessen habe die gleiche PPID, aber der erste Prozess ha s ist eine andere PID. Hier ist ein Beispiel für die Ausgabe ich erhielt:

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 

Meine Frage ist, sollte nicht die übergeordnete PID der beiden Kindprozesse sein ? Hoffe jemand kann erklären, wie alles hier funktioniert und was mache ich (oder denke) falsch.

+3

Was passiert, wenn Sie einen Schlaf hinzufügen, nachdem beide 'printf' fertig sind? –

+0

@MohitJain es tatsächlich behoben, wie ist es passiert? Ich meine einen Sleep Nach dem 'printf' sollte sich eigentlich nichts mehr ändern, da die Prozesse erstellt werden und' fork' das gleiche ... – argamanza

Antwort

5

[Bestätigt aus den Kommentaren]

Ihre Ausgabe ist Timing abhängig. Wenn der übergeordnete Prozess nach den untergeordneten Prozessen abgeschlossen wird, entspricht Ihre Ausgabe den Erwartungen.

Wenn der übergeordnete Prozess vor den untergeordneten Prozessen abgeschlossen wird, kann die Ausgabe überraschend sein (Bevor es kein parent mehr gibt, wäre die übergeordnete ID anders). Sobald der Elternprozess stirbt (endet), wird init oder ein anderer implementation-definierter Prozess (1508 in Ihrem Fall) zum neuen Elternteil des Kindes (der Kinder). Solche Kinder werden Waisenprozess (e) genannt.

Nach dem exit Manpage von The Single UNIX Specification, Version 2:

Die übergeordneten Prozess-ID all vorhandenen Kindprozesse und Zombie-Prozessen des anrufenden Prozesses wird die Prozess-ID eingestellt wird eines implementierungsdefinierten Systemprozesses. Das heißt, diese Prozesse sollen durch einen speziellen Systemprozess vererbt werden.

Um dies zu vermeiden, stellen Sie sicher, dass der Elternprozess zum Zeitpunkt des Abrufs der Eltern-PID aktiv ist. Eine Möglichkeit, dies zu tun, besteht darin, vor dem Beenden eine Wartezeit im übergeordneten (oder allen) Prozess hinzuzufügen.

+1

Macht Sinn, aber '1508' ist trotzdem eine seltsame PID für' init'. – alk

+0

@alk Es ist nicht notwendig init. pid of init ist 1. Tatsächlich ist das ppid von orphan auf implementierungsdefinierte Prozess-ID gesetzt. –

+0

"* Implementation-Defined *" in Bezug auf was, das Betriebssystem? Das ist Linux hier. Mir scheint etwas zu fehlen. – alk

1

Es ist nichts falsch mit Ihrem Code

seine nur, dass Ihre Eltern-Prozess vor Prozesse das Kind verlässt beenden daher Waise sie werden und werden von init oder jede Implementierung definiert Prozess (1508 in Ihrem Fall) angenommen.

versuchen, warten(); Damit Parent die Ausführung aller untergeordneten Prozesse beendet.