Warum existieren open()
und close()
existieren sie im Unix-Dateisystemdesign?
Konnte das Betriebssystem nicht einfach das erste Mal erkennen read()
oder write()
wurde es angerufen und tat, was open()
normalerweise tun würde?
files
filesystems
architecture
api
user5977637
quelle
quelle
open()
existiert. "Konnte das Betriebssystem nicht einfach das erste Mal lesen () oder schreiben () und das tun, was open () normalerweise tun würde?" Gibt es einen entsprechenden Vorschlag für den Zeitpunkt des Abschlusses ?read()
oder aufwrite()
welche Datei Sie zugreifen sollen? Vermutlich auf dem Weg. Was passiert, wenn sich der Pfad der Datei ändert, während Sie darauf zugreifen (zwischen zweiread()
oder zweiwrite()
Aufrufen)?read()
undwrite()
, nur beiopen()
.Antworten:
Dennis Ritchie erwähnt in «Der Entwicklung des Unix Time-Sharing - Systems» , dass
open
undclose
zusammen mitread
,write
undcreat
war in dem System von Anfang an .Ich denke, ein System ohne
open
undclose
wäre nicht undenkbar, aber ich glaube, es würde das Design verkomplizieren. In der Regel möchten Sie mehrere Lese- und Schreibaufrufe durchführen, nicht nur einen. Dies gilt wahrscheinlich insbesondere für alte Computer mit sehr begrenztem Arbeitsspeicher, auf denen UNIX ausgeführt wurde. Ein Handle, das Ihre aktuelle Dateiposition beibehält, vereinfacht dies. Wennread
oderwrite
Wenn sie das Handle zurückgeben würden, müssten sie ein Paar zurückgeben - ein Handle und ihren eigenen Rückgabestatus. Der Handle-Teil des Paares wäre für alle anderen Anrufe unbrauchbar, was diese Anordnung umständlich machen würde. Indem Sie den Status des Cursors dem Kernel überlassen, können Sie die Effizienz nicht nur durch Puffern verbessern. Die Suche nach Pfaden ist auch mit Kosten verbunden. Wenn Sie ein Handle haben, können Sie es nur einmal bezahlen. Außerdem haben einige Dateien in der UNIX-Weltansicht nicht einmal einen Dateisystempfad (oder nicht - jetzt tun sie das mit Dingen wie/proc/self/fd
).quelle
open
/close
erstellen möchten, müssen Sie Dinge implementieren/dev/stdout
, die das Piping zulassen.open()
zuget_inode()
und machten das ganze System steife (unmöglich , die gleiche Datei an mehreren Stellen gleichzeitig lesen / schreiben).Dann müssten alle Aufrufe von
read
undwrite
diese Informationen bei jeder Operation weitergeben:Egal , ob Sie die unabhängigen betrachten Anrufe
open
,read
,write
undclose
seine einfacher als eine Single-Purpose I / O - Nachricht auf Ihrer Design - Philosophie basiert. Die Unix-Entwickler entschieden sich für einfache Operationen und Programme, die auf viele Arten kombiniert werden können, anstatt für eine einzige Operation (oder ein einzelnes Programm), die alles erledigt.quelle
read
undwrite
sind nicht auf Dateien beschränkt, die sich auf einem Dateisystem befinden, und dies ist eine grundlegende Entwurfsentscheidung in Unix, wie pjc50 erklärt.lseek
)Das Konzept der Dateizugriffsnummer ist wichtig, da UNIX als Entwurfsoption festlegt, dass "alles eine Datei ist", auch Dinge, die nicht Teil des Dateisystems sind. B. Bandlaufwerke, Tastatur und Bildschirm (oder Teletyp!), Lochkarten- / Bandleser, serielle Verbindungen, Netzwerkverbindungen und (die wichtigste UNIX-Erfindung) direkte Verbindungen zu anderen Programmen, die als "Pipes" bezeichnet werden.
Wenn Sie sich viele der einfachen Standard-UNIX-Dienstprogramme ansehen
grep
, insbesondere die Originalversionen, werden Sie feststellen, dass sie keine Aufrufe vonopen()
und,close()
sondern nurread
und enthaltenwrite
. Die Dateihandles werden außerhalb des Programms von der Shell eingerichtet und beim Start übergeben. Das Programm muss sich also nicht darum kümmern, ob es in eine Datei oder in ein anderes Programm schreibt.Neben
open
sind die anderen Möglichkeiten Filedeskriptoren zu bekommensocket
,listen
,pipe
,dup
, und ein sehr Heath Robinson Mechanismus für Dateideskriptoren über Rohre zu senden: https://stackoverflow.com/questions/28003921/sending-file-descriptor-by-linux -SteckdoseBearbeiten: Einige Vorlesungsnotizen, in denen die Indirektionsebenen beschrieben werden und wie O_APPEND auf diese Weise sinnvoll funktioniert. Beachten Sie, dass durch das Speichern der Inode-Daten gewährleistet ist, dass das System sie für den nächsten Schreibvorgang nicht erneut abrufen muss.
quelle
creat
und erstelltlisten
kein FD, aber wenn (und wenn) eine Anforderung beim Abhörenaccept
eingeht, wird ein FD für den neuen (verbundenen) Socket erstellt und zurückgegeben.pipe
aber einige Jahre nach dem Start der Entwicklung auf Unix eingeführt.Die Antwort lautet nein, da open () und close () jeweils ein Handle erstellen und zerstören. In bestimmten Situationen möchten Sie möglicherweise sicherstellen, dass Sie der einzige Anrufer mit einer bestimmten Zugriffsebene sind, da beispielsweise ein anderer Anrufer, der in eine Datei schreibt, die Sie gerade analysieren, diese möglicherweise unerwartet verlassen könnte eine Bewerbung in einem unbekannten Zustand oder führen zu einem Livelock oder Deadlock, zB dem Dining Philosophers Lemma.
Auch ohne diese Überlegung sind Auswirkungen auf die Leistung zu berücksichtigen. close () ermöglicht es dem Dateisystem, den von Ihnen belegten Puffer zu leeren (wenn es angemessen ist oder wenn Sie es angefordert haben), eine teure Operation. Mehrere aufeinanderfolgende Änderungen an einem In-Memory-Stream sind weitaus effizienter als mehrere im Wesentlichen unabhängige Lese-, Schreib- und Änderungszyklen in einem Dateisystem, das, wie Sie wissen, eine halbe Welt entfernt über ein Datencenter mit einem Massenspeicher mit hoher Latenz liegt. Selbst bei lokalem Speicher ist der Speicher in der Regel um viele Größenordnungen schneller als der Massenspeicher.
quelle
Open () bietet eine Möglichkeit, Dateien zu sperren, während sie verwendet werden. Wenn Dateien vom Betriebssystem automatisch geöffnet, gelesen / geschrieben und dann wieder geschlossen würden, ließe sich nichts daran ändern, dass andere Anwendungen diese Dateien zwischen den Vorgängen ändern.
Dies kann zwar verwaltbar sein (viele Systeme unterstützen den nicht exklusiven Dateizugriff), die meisten Anwendungen gehen jedoch davon aus, dass sich die geöffneten Dateien nicht ändern.
quelle
Da sich der Pfad der Datei möglicherweise verschiebt, obwohl davon ausgegangen wird, dass er gleich bleibt.
quelle
Das Lesen und Schreiben in ein Dateisystem kann eine Vielzahl von Pufferschemata, die Verwaltung des Betriebssystems, die Datenträgerverwaltung auf niedriger Ebene und eine Vielzahl anderer potenzieller Aktionen umfassen. Die Aktionen von
open()
undclose()
dienen als Vorbereitung für diese Art von Aktivitäten unter der Haube. Verschiedene Implementierungen eines Dateisystems können nach Bedarf stark angepasst werden und bleiben für das aufrufende Programm dennoch transparent.Wenn das Betriebssystem nicht geöffnet / geschlossen hätte, dann müssten diese Dateiaktionen mit
read
oderwrite
jedes Mal Initialisierungen, Pufferlöschung / -verwaltung usw. durchführen. Das ist ein großer Aufwand für sich wiederholende Lese- und Schreibvorgänge.quelle
Das Unix-Mantra ist "Biete eine Möglichkeit, Dinge zu tun", was "Zerlegen" in (wiederverwendbare) Teile bedeutet, die nach Belieben kombiniert werden können. In diesem Fall trennen Sie die Erstellung und Zerstörung von Dateihandles von ihrer Verwendung. Wichtige Vorteile kamen später mit Pipes und Netzwerkverbindungen (sie werden auch über Datei-Handles bearbeitet, aber sie werden auf andere Weise erstellt). Nur so ist es möglich, Dateihandles zu versenden (z. B. an untergeordnete Prozesse als "offene Dateien" weiterzugeben
exec(2)
, die überleben , und sogar an nicht verwandte Prozesse über eine Pipe). Insbesondere, wenn Sie einen kontrollierten Zugriff auf eine geschützte Datei anbieten möchten. So können Sie zB öffnen/etc/passwd
Übergeben Sie dies zum Schreiben an einen untergeordneten Prozess, der diese Datei nicht zum Schreiben öffnen darf. (Ja, ich weiß, dies ist ein lächerliches Beispiel. Sie können es gerne mit etwas Realistischerem bearbeiten.)quelle