Hallo Gemeinde Ich habe ein Delphi-Programm, welches u.a. 2 Threads benützt: Thread A erstellt einen Stream zu einer Datei um darin Daten zu speichern, welche über einen Com-Port empfangen werden. Thread B benützt den selben Stream, um Daten aus der Datei zu lesen und anzuzeigen. Das Problem ist, dass beide Threads jeweils nach gutdünken Seek(n) durchführen. Dies bewirkt, dass manchmal die Daten des Thread A an die falsche Stelle geschrieben werden. Dieses Design ist m.E. unbrauchbar. Wie macht man das besser? Meine Idee: Zwei verschiedene Streams auf die selbe Datei erzeugen, einer r/w der andere r. Beide können unabhängig Seek-en. Zielsystem: Windows 98..7
Sieh Dir die Dokumentation der Win32-Dateifunktionen wie z.B. CreateFile an, da werden Flags spezifiziert, die beim Öffnen bzw. Erzeugen von Dateien angegeben werden können. Und dazu gehören auch welche, die den simultanen Mehrfachzugriff auf eine Datei erlauben. Die Dateiposition gehört zum Dateihandle und nicht zur Datei, wenn also eine Datei mit zwei Handles geöffnet wird, kann auf jedem der Handles unabhängig vom anderen die Dateiposition geändert werden.
oder mit OVERLAPPED IO arbeiten. http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx
Rufus Τ. Firefly schrieb: > Sieh Dir die Dokumentation der Win32-Dateifunktionen wie z.B. CreateFile > an, da werden Flags spezifiziert, die beim Öffnen bzw. Erzeugen von > Dateien angegeben werden können. Und dazu gehören auch welche, die den > simultanen Mehrfachzugriff auf eine Datei erlauben. > > Die Dateiposition gehört zum Dateihandle und nicht zur Datei, wenn also > eine Datei mit zwei Handles geöffnet wird, kann auf jedem der Handles > unabhängig vom anderen die Dateiposition geändert werden. Du sprichst hier aber von 2 verschiedenen Sachen: Das eine sind Overlapped IOs, die auf ein Dateihandle angewendet werden. Das Andere ist die gleiche Datei mehrmals mit verschiedenen Handles geöffnet zu haben. Ob letzteres funktioniert ist sowohl von den Flags des CreateFile, als auch von der zu öffnenden (Geräte)Datei abhängig. COM-Ports kann man nicht mehrfach öffnen (auch nicht wenn man einmal readonly und einmal writeonly öffnet) Ein Beispiel für Overlapped IO am Beispiel des Comports hab ich letztens erst implementiert (--> Beitrag "PortableSerialLib - Portable Serial Port Library" )
Vlad Tepesch schrieb: > Du sprichst hier aber von 2 verschiedenen Sachen: > Das eine sind Overlapped IOs, die auf ein Dateihandle angewendet > werden. Wo habe ich overlapped IO erwähnt?
Rufus Τ. Firefly schrieb: > Vlad Tepesch schrieb: >> Du sprichst hier aber von 2 verschiedenen Sachen: >> Das eine sind Overlapped IOs, die auf ein Dateihandle angewendet >> werden. > > Wo habe ich overlapped IO erwähnt? sorry, du hast recht. Irgendwie ist wohl der nächste Beitrag ins periphere Gesichtsfeld und ins Unterbewussstsein gerutscht.
Danke für die Antworten. Ich habe ein kleines Testprogramm erstellt, und es funktioniert soweit ganz gut.
nach einer exception wird bei keiner mir bekannten Programmiesprache noch der darauf folgende code ausgeführt: > raise Exception.Create(Format('Oops - error opening disk: %d', [GetLastError])); > mHandle1 := INVALID_HANDLE_VALUE;
und WAS funktioniert da jetzt? du schreibst ja nichts in die datei ? (oder hab ich es übersehen) interessant wird es ja erst, wenn du Daten schreibst (vorallem WANN und wie Vollständig die dann dem 2. thread beim lesen zur Verfügung stehen..) wirklich in die datei geschrieben wird IMHO erst, wenn genung daten vorhanden, oder bei zwei THREADS würde ich das auf keine fall so machen (eigentlich nicht mal bei 2 tasks,..)
vermutlich sind für wahlfreie Lese- und Schreib-Zugriffe auf die Datei Memory Mapped Files geeigneter. damit habe ich aber noch nie was gemacht.
Das ist nur ein rudimentäres Funktionsmuster. Ich wollte sehen, ob ich zwei unabhängige Seek-Positionen realisieren kann. Das Funktioniert tatsächlich. Ja das ist wohl Unsinn, nach einer Exeption noch etwas initialisieren zu wollen. Das ist mir auch nicht klar, ob frisch geschriebene Daten vom Thread B auch gelesen werden können. Das wird sich dann zeigen, sobald ich die Applikation umgebaut habe.
Sieh Dir doch auch mal FileLock() bzw. FileLockEx() an, wenn Du wirklich unabhängige Zugriffe auf eine Datei ausführst.
Lock schrieb: > Sieh Dir doch auch mal FileLock() bzw. FileLockEx() an, wenn Du wirklich > unabhängige Zugriffe auf eine Datei ausführst. in der doku steht aber: > Locks the specified file for exclusive access by the calling process und er hat ja nur ein process - damit hilft das kaum weiter.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.