Std::fstream Offene Datei neu einlesen
-
Hallo,
ich habe folgendes Problem: Ich habe mehrere Reader-Threads, welche alle mit einem eigenen fstream eine Datei öffnen und lesen können. Es gibt einen Writer, welcher in diese Datei schreiben kann. Vor dem Schreiben werden die Reader angehalten und nach dem Schreiben wieder aufgeweckt. In letzter Zeit kam es öfters vor, dass die Reader nicht die neuen Daten gelesen haben, sondern noch die Alten (ich nehme an aus dem Puffer).Als erste Lösung habe ich jetzt erstmal alle geöffneten Reader nach dem Schreiben die Datei mit fstream::close() schliessen und sofort wieder mit fstream::open(…) öffnen lassen. Das funktioniert erstmal so.
Jetzt zu meiner Frage: Gibt es eine bessere Möglichkeit als diese?
-
Warte! Verstehe ich das richtig, dass du mit mehreren Threads auf eine Datei zugreifst und das auch noch konkurrierend, also mit Schreiboperationen?
Das klingt ziemlichst ineffizient, daher die Frage: Was machst du bzw. was hast du vor?
IO ist perse schonmal recht langsam, d.h. das zu parallelisieren lohnt sich meist kaum bzw. sollte gut durchdacht sein. Aber dabei dann noch Data Races zu beachten macht das recht schwierig und fehleranfällig.
Reicht dir eventuell nicht ein gemeinsamer Speicherbereich, wo du was reinschreibst? Oder vielleicht noch sowas wie Memory Mapped Zeugs?
-
@ Skym0sh0 Mehrere lesende Zugriffe (die konkurrieren per se nicht). Wenn geschrieben wird, macht das der Writer und die Reader schlafen so lange. Wenn die Reader wieder aufgeweckt werden, ist nicht immer gewährleistet, dass die neuesten Daten gelesen werden.
Meine Frage ist nach wie vor; kann man die Daten ohne Schließen und wieder Öffnen auffrischen.
-
Wenn man sich die Doku zu ifstream anschaut, stolpert man über sync. Dann stellt man sich unweigerlich die Frage, ob du zu faul bist, mal in die Doku zu schauen oder ob es nicht funktioniert und du zu faul bist, das hier zu erwähnen.
-
Allgemein: Tu das nicht! Mach Dateien nur in einem Thread zum Schreiben auf. Und normalerweise auch zum Lesen. Das ist in aller Regel vielfach effizienter und vor allem hundertfach weniger fehleranfällig!
Was soll das überhaupt werden, dass ein Programm aus seinen selbstgeschriebenen Dateien liest? Eine Art Inter-Thread-Kommunikation über Dateien?

-
@manni66 Danke für Deinen Hinweis! Habe das heute Morgen in der Doku unter http://www.cplusplus.com/reference/fstream/fstream/ glatt übersehen.
Aber auch kann Dir helfen; schau mal hier http://www.enzyklo.de/Begriff/Soziallegastheniker
-
@SeppJ Ich habe einen Server gebaut, welcher mehrere Clients auf Daten in Dateien zugreifen lässt. Die lesenden Clientrepräsentationen im Serverprozess sind Threads. Wenn ein Client was schreibt, werden alles lesenden Clientrepräsentationen angehalten, ein Writer aktiviert der schreibt und dann alle lesenden Clientrepräsentationen wieder gestartet. Also ein Writer der exklusiv auf die Daten zum Ändern zugreift und mehrere Leser welche parallel lesen können. Das funktionierte bislang auch gut (habe es mit mehreren schreibenden und lesenden Clients getestet). Seit dem Umstieg auf Windows 10 lesen jetzt einige Clients alte Daten. Das Phänomen wurde ich wie beschrieben los und war mir nur unsicher ob es nicht eine bessere Möglichkeit gibt. Habe fstream::sync() einfach übersehen und werde es gleich mal ausprobieren.
-
Hast du da etwa eigenhändig ein DBMS gebaut?

-
Hört sich eher wie ein eigenes SMB-ähnliches Protokoll. Oder FTP.
-
@SeppJ Ja.
@manni66 Zur Info; fstream::sync() tut nicht das, was ich will. Bleibe also erst mal beim Öffnen und Schließen.
Danke
-
Helmut.Jakoby schrieb:
@SeppJ Ja.
Und das kommt dir wie eine gute Idee vor?
Server + (separates!) DBMS ist doch eine klassische Kombination. Warum nicht auf die bekannten Gewinner setzen?
-
@SeppJ 1. Ich habe früher mit FastObjects bzw. POET gearbeitet. Diese Datenbank wird nicht mehr für C++ unterstützt. Ich wollte aber persistente Objekte definieren, die ich einfach speichern und ändern kann (Das Klassendesign ist das Datenbankdesign). Also habe ich FastObjects (bislang ohne Querrys oder OQL) nachempfunden. Das funktioniert schon ganz gut. Man kann mit oder ohne Server arbeiten, es muss nur die Schnittstelle mit einem anderen Parameter aufgerufen werden. Ich habe unterschiedliche Locks (auf Menge von Objekten einer Klasse und auf einzelne Objekte), kann Transaktionen geschachtelt verarbeiten und den Client benachrichtigen wenn sich Objekte, die er beobachtet, durch andere Clients geändert haben (Objekte können sich automatisch aktualisieren, wenn sie von anderen geändert wurden). Sogar Mehrfachvererbung funktioniert. Im ersten Wurf sind die Objekt-Daten in Text-Tabellen im Filesystem gespeichert und sind über Objekt-IDs zu finden… ich glaube jetzt langweilige ich langsam.
2. Ich wollte wissen wie man so etwas bauen kann (Sockets und Threads haben mich auch interessiert).
3. Und wenn keiner mehr was baut, dann behalten wir immer die bekannten Gewinner.