Autor Thema: Filedeskriptoren und Buffers  (Gelesen 8260 mal)

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« am: 03. November 2015, 23:44 »
Hallo zusammen,

Da jedes Unterprogramm die Filedeskriptoren des Vaterprozesses erbt, was passiert denn, wenn jetzt beide Prozesse gleichzeitig in die gleiche Datei schreiben (Z.B. stdin)?

Ich dachte nämlich, dass ich Dateien einfach in den virtuellen Addressraum "mounte" (mit Shared Memory), so dass ich das auch gleich als Buffer verwenden würde. Ist das möglich oder gibt es da bestimmte Regeln?
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 04. November 2015, 09:07 »
Ich gehe im Folgenden mal davon aus, dass du von POSIX redest. Falls das falsch ist, korrigier mich bitte.

Erstmal dein Beispielszenario, das aber einfacher ist, als du dachtest: Wenn zwei Prozesse gleichzeitig nach stdin schreiben, bekommen sie beide gleichzeitig EBADF. ;)

Wenn du nach stdout schreibst, also mit write() auf FD 1, dann ist irgendjemand zuerst dran und dessen Daten werden dann zuerst geschrieben. Danach kommt der andere Prozess und hängt seine Daten dahinter. Wenn du unter Linux mal einen Prozess in den Hintergrund geschickt hast, der Ausgaben macht, dann kennst du das Ergebnis, dass sich die Ausgaben von der Shell und vom Hintergrundprogramm auf dem Terminal vermischen.

Mit mmap() sieht die Sache anders aus, wobei ich nicht weiß, ob man Character Devices überhaupt sinnvoll mmapen kann. Es soll ja auch irgendwas passieren, nachdem du auf das Gerät geschrieben hast statt dass die Daten nur in einem Cache landen. Du müsstest wahrscheinlich bei jedem Schreibzugriff auf die Page faulten, dir merken, dass da gerade Daten reinkommen, den Prozess weiterlaufen lassen und irgendwann später die Ausgabe machen und die Page wieder schreibschützen. Was passiert, wenn der gemappte Puffer einmal vollgeschrieben ist, finde ich auch nicht ganz klar. Du könntest versuchen, das als Ringpuffer aufzubauen, aber wie bekommst du mit Speicherzugriffen auf einen gemmapten Bereich eine blockierende Operation hin, wenn der Ring voll ist?

Insofern würde ich stark dazu tendieren, mmap nur für normale Dateien und Blockgeräte zuzulassen, aber nicht für Character Devices, Pipes, Sockets usw. (POSIX verlangt: "The mmap() function shall be supported for regular files, shared memory objects, and  typed memory objects.  Support for any other type of file is unspecified")
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen