Ich habe einige Abfragen im Zusammenhang mit den Systemaufrufen von read () / pread () in einer Multithread-Umgebung
Ich verwende Mac-OSX, das auf FreeBSD basiert, wenn das irgendwie hilft Ich verwende diese Datei nur im Lesemodus und nicht im Lese- / Schreibmodus Und die Sprache ist c / c ++
Angenommen, wir haben eine Datei auf der Festplatte AAAABBBBCCCCDDDEEEE ....
und 4 Alphabete passen auf eine Seite der Datei
Also Seite1: AAAA
Seite2: BBBB ..... und so weiter
Jetzt initiiere ich einen Lese-Systemaufruf von zwei verschiedenen Threads mit demselben Dateideskriptor Meine Absicht ist es, die erste Seite von Thread 1 zu lesen, die zweite Seite von Thread 2, ... und so weiter.
lesen (fd, buff, sizeof (Seite));
Von der man-Seite wird mir gesagt, dass lesen auch den Dateizeiger inkrementiert, also werde ich definitiv verzerrte Antworten wie
bekommenABCC ABBB .. usw. (ohne bestimmte Reihenfolge)
um dies zu beheben, kann ich pread ()
verwenden"Pread () führt die gleiche Funktion aus, liest aber aus Position in der Datei ohne Änderung des Dateizeigers "// from man pages
Aber ich bin mir nicht sicher, ob die Verwendung von pread mir tatsächlich bei meinem Ziel helfen wird, denn obwohl der interne Dateizeiger nicht inkrementiert wird, gibt es keine Garantie dafür, dass die Antworten nicht durcheinander geraten.
Alle meine Daten sind Seiten ausgerichtet und ich möchte eine Seite von jedem Thread wie
lesenThread 1 lautet: AAAA Thread 2 lautet: BBBB Thread 3 liest: CCCC ... ohne den Inhalt tatsächlich zu verstopfen.
Ich habe auch einen Beitrag Ist es sicher, () von einer Datei zu lesen, sobald write () zurückkommt?
aber es war nicht sehr nützlich.
Ich bin mir auch nicht sicher, ob read () tatsächlich das Problem hat, dass ich an die Datei denke. Die Datei, die ich lese, ist eine Binärdatei und daher ist es schwierig, sie schnell manuell zu lesen und zu verifizieren ..
Jede Hilfe wird geschätzt
read
und write
ändern die Position der zugrunde liegenden geöffneten Datei. Sie sind "threadsicher" in dem Sinne, dass Ihr Programm kein undefiniertes Verhalten (Absturz oder Schlimmeres) haben wird, wenn mehrere Threads IO gleichzeitig auf derselben geöffneten Datei ausführen, wobei die Reihenfolge und Atomizität der Operationen je nach Art der Datei und die Implementierung.
Andererseits ändern pread
und pwrite
die Position in der geöffneten Datei nicht. Sie wurden genau zu dem von Ihnen gewünschten Zweck zu POSIX hinzugefügt: Sie führen IO-Operationen für dieselbe geöffnete Datei aus mehreren Threads oder Prozessen aus, ohne dass sich die Operationen gegenseitig stören. Wenn Sie pread
und pwrite
(oder mehrere Aufrufe von pwrite
) mit sich überlappenden Teilen der Datei mischen, können Sie trotzdem Probleme mit der Bestellung bekommen. Solange Sie dies jedoch vermeiden, sind sie vollkommen sicher für das, was Sie tun möchten.
fcntl
advisory locks sind Sperren für einen Bereich der Datei. Sie können dies nützlich finden, um Lese- und Schreibvorgänge in derselben Region zu serialisieren, während gleichzeitige Zugriffe auf separate Bereiche zulässig sind.
Mehrfache Lesesperren sind gleichzeitig erlaubt, während eine einzige Schreibsperre alle anderen sperrt.
Seien Sie gewarnt, dass alle Dateiverriegelungsmechanismen bei einigen Konfigurationen auf allen Plattformen subtil unterbrochen sind .
> Geben Sie eine Mutex-Sperre zwischen den beiden Threads frei, aktivieren Sie die Sperre im Thread, bevor sie gelesen wird, und entsperren Sie die Sperre, wenn der korrekte Lesevorgang abgeschlossen ist. Siehe pthread_mutex_create
, pthread_mutex_lock
und pthread_mutex_unlock
.
Tags und Links c multithreading thread-safety asynchronous