Betrachten Sie den folgenden Code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i = 0; i < 2; i++)
{
fork();
printf(".");
}
return 0;
}
Dieses Programm gibt 8 Punkte aus. Wie kann das möglich sein? Sollte es nicht stattdessen 6 Punkte geben?
Antworten:
Das
fork()
Primitive regt oft die Vorstellungskraft an. Bis Sie ein Gefühl dafür bekommen, sollten Sie auf Papier nachvollziehen, was jeder Vorgang ist, und die Anzahl der Prozesse berücksichtigen. Vergessen Sie nicht, dass fork () eine nahezu perfekte Kopie des aktuellen Prozesses erstellt. Der wichtigste Unterschied (für die meisten Zwecke) besteht darin, dassfork()
der Rückgabewert zwischen Eltern und Kind unterschiedlich ist. (Da dieser Code den Rückgabewert ignoriert, macht er keinen Unterschied.)Zunächst gibt es also einen Prozess. Dadurch wird ein zweiter Prozess erstellt, bei dem beide einen Punkt und eine Schleife drucken. Bei der zweiten Iteration erstellt jeder eine weitere Kopie, sodass vier Prozesse einen Punkt drucken und dann beenden. So können wir problemlos sechs Punkte berücksichtigen, wie Sie es erwarten.
Was jedoch
printf()
wirklich tut, ist die Ausgabe zu puffern. Der erste Punkt aus der Zeit, als es nur zwei Prozesse gab, wird beim Schreiben nicht angezeigt. Diese Punkte verbleiben im Puffer, der bei fork () dupliziert wird. Erst wenn der Prozess beendet ist, wird der gepufferte Punkt angezeigt. Vier Prozesse drucken einen gepufferten Punkt, und der neue ergibt 8 Punkte.Wenn Sie dieses Verhalten vermeiden möchten, rufen Sie
fflush(stdout);
danach anprintf()
.quelle
fork()
erstellt nicht 2, sondern beendet, sondern nur 1 weiteren Prozess.Sie haben nicht festgeschriebene Puffer in den Ausgabestreams . stdout ist zeilengepuffert und der Puffer wird zusammen mit dem Rest des Prozesses repliziert. Wenn das Programm beendet wird, wird der nicht festgeschriebene Puffer zweimal geschrieben (einmal für jeden Prozess). Beide verwenden
und
Zeigen Sie das Problem nicht.
In Ihrem ersten Beispiel erstellen Sie vier Prozesse, deren Ausgabestream-Puffer jeweils zwei Punkte enthält. Wenn jeder Stream beendet wird, wird sein Puffer geleert und acht Punkte generiert.
quelle
wenn i = 0
Prozess_1: Gepufferter Text = 1 Punkt
Process_2 (erstellt von Process_1): Gepufferter Text = 1 Punkt
wenn i = 1
Process_3 (erstellt von Process_1): Erbt 1 gepufferten Punkt von Process_1 und druckt 1 Punkt selbst. Insgesamt druckt Process_3 2 Punkte.
Process_4 (erstellt von Process_2): Erbt 1 gepufferten Punkt von Process_2 und druckt 1 Punkt selbst. Insgesamt druckt Process_4 2 Punkte.
Prozess_1: Druckt 2 Punkte (Ein gepufferter Punkt bei i = 0 und ein weiterer Punkt bei i = 1)
Prozess_2: Druckt 2 Punkte (Ein gepufferter Punkt bei i = 0 und ein weiterer Punkt bei i = 1)
Endgültige Ausgabe: 8 Punkte. :) :)
quelle