GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Können mehrere Threads/Prozesse ohne Synchronisierung gleichzeitig aus/in nicht überlappende Bereiche einer Datei lesen/schreiben?

Ich würde gerne wissen, ob Linux-Lese- / Schreibsystemaufrufe nicht synchronisierte Lese- / Schreibvorgänge (nicht anhängende Schreibvorgänge) in nicht überlappenden Regionen einer einzelnen Festplattendatei von mehreren Threads oder Prozessen unterstützen. Jeder Thread sucht in seinem eigenen Bereich der Datei und liest/schreibt ausschließlich aus/in diesen Bereich, ohne sich mit den Bereichen zu überschneiden, in denen andere Threads arbeiten.

POSIX legt in XSH 2.9.7 fest, dass im Wesentlichen alle I/O-Funktionen bezüglich ihrer POSIX-spezifizierten Wirkungen atomar zueinander sind. Eine lange Liste der spezifischen Funktionen, auf die dies zutrifft, ist angegeben, und open() , lseek() , read() , write() , und close() sind alle dran. Daher

Wenn zwei Threads jeweils eine dieser Funktionen aufrufen, soll jeder Aufruf entweder alle spezifizierten Effekte des anderen Aufrufs sehen oder keine davon.

Das hängt nicht von irgendeiner externen Synchronisation ab, selbst für Operationen auf Dateideskriptoren, die mit derselben offenen Dateibeschreibung verbunden sind.

Es kann mehrere offene Dateibeschreibungen für dieselbe Datei geben, selbst in einem einzigen Prozess (siehe zum Beispiel die Handbuchseite für open(2)). Angesichts mehrerer Threads, die read() ausführen und write() Operationen an nicht überlappenden Bereichen derselben regulären Datei, über Dateideskriptoren, die sich auf verschiedene offene Dateibeschreibungen beziehen , bietet POSIX keine Grundlage, um zu erwarten, dass sich diese Operationen gegenseitig stören, unabhängig von der externen Synchronisation der beteiligten Threads. In der Praxis funktioniert es gut.

Wo Sie in Schwierigkeiten geraten können ist, wenn die beteiligten Threads versuchen, Dateideskriptoren zu verwenden, die auf dieselbe offene Dateibeschreibung verweisen. Diese müssen nicht denselben Dateideskriptorwert haben (also dup() Das Hinzufügen eines Dateideskriptors hilft hier nicht), noch müssen die Threads zum selben Prozess gehören, damit die Situation auftritt. Jede offene Dateibeschreibung hat eine einzige zugeordnete Dateiposition, wenn also zwei verschiedene Threads versuchen, Aufgaben auszuführen, die jeweils separat erforderlich sind Setzen des Datei-Offsets und Übertragen von Daten in oder aus der Datei, und wenn sie dieselbe offene Dateibeschreibung verwenden, reicht die Atomarität der einzelnen Funktionsaufrufe nicht aus, um sicherzustellen, dass die Lese- und Schreibvorgänge an den beabsichtigten Positionen ausgeführt werden. In diesem Szenario ist eine Synchronisierung erforderlich.

Alternativ, wie @maximegorushkin in Kommentaren und @bk2204 in einer anderen Antwort bemerkte, der pread() und pwrite() Funktionen führen Positionierung und Datenübertragung in einem einzigen Aufruf durch. Diese befinden sich auch auf der Liste der atomaren E/A-Funktionen und überwinden die Trennung der Positionierung von der Datenübertragung auf einer Per-Data-Transfer-Basis. Ihre Verwendung erfordert besondere Sorgfalt und Buchhaltung, und es gibt Szenarien, in denen dies nicht angemessen ist, aber es kann dennoch für den jeweiligen Fall praktikabel sein.

Daher , wenn zwei verschiedene Threads ohne Synchronisierung mit derselben Datei arbeiten möchten, besteht der sicherste und allgemeinste Ansatz darin, dass jeder die Datei unabhängig voneinander öffnet. Sie stören sich dann nicht gegenseitig, solange ihre E/A-Operationen auf disjunkte Bereiche der Datei beschränkt sind. Auch das Arbeiten mit überlappenden Bereichen der Datei ist nicht ausgeschlossen, aber das führt zu komplexeren, anwendungsspezifischen Überlegungen.


Ja, das ist möglich. Die pread und pwrite Mit Funktionen können Sie an einem bestimmten Offset aus einer Datei lesen und schreiben, ohne den Datei-Offset zu ändern. Sie wurden speziell entwickelt, um das Lesen und Schreiben in Multithread-Programmen zu ermöglichen.

Sie sollten beachten, dass pwrite gegen POSIX verstößt auf einem Dateideskriptor, der mit O_APPEND geöffnet wurde schreibt immer an das Ende der Datei.


Linux
  1. Lesen und schreiben Sie in dieselbe Datei unter Linux, ohne sie zu überschreiben?

  2. Sudoedit Vim Force Write (Update) ohne Beenden?

  3. Lesen von Zeilen aus einer Datei mit Bash:Für Vs. Während?

  4. Kann read(2) Null zurückgeben, wenn es nicht bei EOF ist?

  5. Mongodb kann nicht aus Debian entfernt, gelöscht oder deinstalliert werden

So verschieben Sie mehrere Dateitypen gleichzeitig von der Befehlszeile aus

Kopieren Sie eine Datei in mehrere Verzeichnisse von der Befehlszeile unter Linux

Lesen/Schreiben an einer seriellen Schnittstelle ohne Root?

Wie kann ich mehrere Dateien in VIM bearbeiten?

Wie kann ich von der Befehlszeile aus in dmesg schreiben?

Wie kann ich eine Binärdatei aus einer .py-Datei erhalten?