05.11.2013 Aufrufe

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

Zahn - Unix-Netzwerkprogramminerung mit Threads, Sockets und SSL

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

2.5 Prozeßkontrolle 83<br />

so aussieht, als hätte der Elternprozeß diese Textzeile aus <strong>und</strong>urchsichtigen<br />

Gründen zweimal erzeugt, hat eine ganz einfache Erklärung: Die Kontrollausgabe<br />

wurde vor dem Aufruf von fork() vom ursprünglichen Prozeß<br />

(PID 25988) <strong>mit</strong> printf() erzeugt. Erfolgt die Ausgabe auf das Terminal,<br />

so erscheint diese Kontrollausgabe aufgr<strong>und</strong> der zeilenweisen Pufferung der<br />

Standard-Bibliothek von ANSI/ISO C sofort. Wird die Ausgabe aber z. B.<br />

in eine Datei umgeleitet, so schlägt die vollständige Pufferung der Standard-<br />

Bibliothek zu. In diesem Fall wird die Ausgabe in einem internen Datenpuffer<br />

der Standard-Bibliothek zwischengespeichert <strong>und</strong> deshalb von fork() <strong>mit</strong>samt<br />

dem Zwischenspeicher in das neue Prozeßabbild übernommen.<br />

In unserem Beispiel wird dieser interne Datenpuffer von beiden Prozessen<br />

erst am Programmende geleert <strong>und</strong> da<strong>mit</strong> tatsächlich ausgegeben. Aus diesem<br />

Gr<strong>und</strong> hat die eingeführte Kunstpause keinen Einfluß auf das Ausgabeverhalten<br />

der beiden Prozesse <strong>und</strong> die Ausgaben erscheinen in diesem Beispiel<br />

sequentialisiert. Außerdem erscheint der Text Prozeß 25988: Starte fork()“<br />

”<br />

doppelt. Die erste Zeile der Ausgabe rührt dabei nicht vom Eltern-, sondern<br />

vom Kindprozeß her, wenn auch der Inhalt der Ausgabe vom Elternprozeß<br />

erzeugt wurde <strong>und</strong> daher die Prozeß-ID auch auf diesen hindeutet.<br />

Es zeigt sich also einmal mehr, daß bei der System- <strong>und</strong> Netzwerkprogrammierung<br />

im Zusammenspiel <strong>mit</strong> der Standard Ein- <strong>und</strong> Ausgabe höchste Sorgfalt<br />

geboten ist. Hätten wir an Stelle der Funktion printf() aus der Standard-<br />

Bibliothek den Systemaufruf write() verwendet, wäre der beschriebene Effekt<br />

mangels Pufferung natürlich erst gar nicht eingetreten.<br />

Das vorangegangene Beispiel zeigt darüber hinaus, daß der Kindprozeß bei<br />

fork() in der Tat eine Kopie der Dateideskriptor-Tabelle aus dem Elternprozeß<br />

erhält. Abbildung 2.9 illustriert, wie die korrespondierenden Dateideskriptoren<br />

aus den Dateideskriptor-Tabellen von Eltern- <strong>und</strong> Kindprozeß jeweils<br />

auf die selbe Beschreibung der offenen Datei verweisen.<br />

Erst durch diese gemeinsame Nutzung der selben Beschreibung wird es<br />

möglich, daß die Umlenkung der Ausgabe, wie wir sie im zweiten Testlauf<br />

wie selbstverständlich eingesetzt haben, auch tatsächlich für beide Prozesse<br />

funktioniert <strong>und</strong> daß sich darüber hinaus die Ausgaben von Eltern- <strong>und</strong><br />

Kindprozeß nicht gegenseitig überschreiben.<br />

2.5.3 Prozesse synchronisieren<br />

Neue Prozesse werden gestartet, um ihnen eine spezielle Aufgabe <strong>mit</strong> auf<br />

den Weg zu geben. Die von einem Webserver gestarteten Kindprozesse sollen<br />

z. B. jeweils die Anfrage eines Webbrowsers beantworten. Die Übergabe<br />

einer solchen Aufgabe an einen Kindprozeß findet meist über den Adreßraum<br />

im Elternprozeß statt, der beim fork() auf den neuen Prozeß übertragen<br />

wird. Neben der Funktion, einen neuen Prozeß zu erzeugen, bildet die fork()-<br />

Funktion da<strong>mit</strong> gleichzeitig einen impliziten Synchronisationspunkt zwischen

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!