Frage

Sorry, wenn ich diese Frage bin wieder zu fragen, aber überprüfen möchten!

Ich habe zwei Prozesse P1 und P2.

P1 ist ein Schriftsteller (Produzent).
P2 ist ein Leser (Consumer).

Es gibt einige gemeinsam genutzten Speicher oder eine Datei, die P1 schreibt und sobald P1 schreibt, sollte P2 zum Lesen mitgeteilt werden.

Jetzt nach meinem Verständnis Pseudo-Code für P1 sein sollte

Open shared file
Create a named event("Writedone") to signal write for P2 process
Do some processing on file
Mutex.Lock()
Write to File
Mutex.Unlock()
Signal named Event.
CloseHandle on file

Jetzt in P2

Open handle to Shared file
Open handle to named event
WaitForSingleEvent on named event("Writedone")
Read from file
CloseHandle on file

Fragen:

  1. Ist es erforderlich Schlösser in den Leser haben? Der Leser wird nur die Datei lesen und es nicht ändern. Also denke ich, keine Sperren im Leser erforderlich sind. Gedanken? Kann es in einigen Fällen ohne Sperren schief gehen?
  2. Ich Öffnen und Schließen Griffe zum jedes Mal beim Lesen und Schreiben der Datei. Ich denke, dass nicht erforderlich ist. Ich kann die Datei-Handle im Konstruktor öffnen und es in der Destruktor-Leser und -Schreiber schließen. Aber kann ich aus der Datei lesen, wenn sie in schriftlicher Form verwendet wird?

EDIT:. Jedesmal, Schreiber ist 10 Bytes am Ende der Datei und Leser Schreiben soll die neuesten 10 Bytes von Autor geschrieben lesen

War es hilfreich?

Lösung

Die Antwort lautet: Verriegelung notwendig ist, wenn (und nur dann) beide Threads die gleichen gemeinsame Ressourcen zur gleichen Zeit verwenden können. Es gibt nicht genügend Informationen über die konkrete Umsetzung, aber ich habe einige Bemerkungen:

  1. während des Schreibens nur sperren macht keinen Sinn. Es fügt nur einige Overhead, aber nicht von einem gleichzeitigen Zugriff zu verhindern, bis der Leser auch korrekt verriegelt ist.
  2. Locking würde notwendig sein, wenn Dateioperationen, die Strukturen ändern mit der Datei-Deskriptoren verbunden sind, in irgendeiner Weise nicht synchronisiert. Es kann vorkommen, dass P1 Schreiben in die Datei starten könnte, wenn P2 noch liest. Wenn Lese- und Schreiboperationen die gleichen Systemstrukturen ohne zugrunde liegende Synchronisation ändern werden Sie sich mit beschädigten Daten beenden. Es ist schwer zu sagen, ob dies hier der Fall ist, weil Sie nicht, welche spezielle Funktion (Bibliotheken) erwähnt haben Sie verwendet. Datei-Operationen werden auf den meisten Systemen synchronisiert werden, so sollte es kein Problem sein.
  3. Von dem, was Sie schrieb über „10 Byte Teile von Informationen“, scheinen die expliziten Sperren nicht notwendig zu sein (es sei denn, # 2 ist es nicht zu verhängen). P1 erzeugt Quanten von Daten. Wenn die Daten bereit sind zu lesenden benachrichtigt P1 P2 über die (durch das Ereignis, Veranstaltung Gang sollte intern synchronisiert werden, sowieso). P2 weiß, dass es Quanten von Daten zu lesen und dann für die nachfolgende Meldung warten muss. Es kann vorkommen, dass eine nachfolgende Meldung gesendet werden würde, bevor vorherige behandelt wird. So muss die Ereignisse irgendwie Warteschlange werden. Sie können auch Semaphore statt Ereignisse Benachrichtigung verwenden.

Andere Tipps

Sie müssen die Leser eine Sperre zu erhalten - die Verwendung von Ereignissen kein Ersatz. Ohne sie könnte ein Schriftsteller schriftlich an jedem beliebigen Punkt in dem Lesercode beginnen.

Sie müssen unbedingt die Verbraucher, um zu sperren die Hersteller von Anhängen an die Datei zu verhindern, bevor der Leser lesen kann. Stellen Sie sich folgendes Szenario vor:

Producer writes and signals
Consumer receives signal
Consumer opens the file
Producer fires again and writes another 10 bytes
Producer signals
Consumer reads the last 10 bytes
Consumer closes the file

Was passiert, hängt davon ab, ob Ihr benannte Ereignis manuell zurückgesetzt oder Auto-Reset. Wenn es Auto-Reset ist, dann wird der Verbraucher das zweite Signal sehen, und gehen Sie zurück und lesen Sie wieder das gleiche. Wenn es manuell zurückgesetzt ist, dann wird der Verbraucher geht das Ereignis zurückgesetzt und das letzte, was vermisst, dass der Produzent schrieb.

Hinweis

, dass auch mit der Sperre Sie eine Race-Bedingung, wenn der Hersteller schnell genug reagieren kann. Das heißt, könnte der Hersteller in der Lage sein, einen zweiten Datensatz in die Datei zu setzen, bevor der Verbraucher die ersten lesen kann.

Es scheint, dass das, was Sie hier haben, eine FIFO-Warteschlange in einer Datei implementiert ist, und Sie sind abhängig von der Fähigkeit der Verbraucher Daten schneller zu verarbeiten als der Produzent es schaffen kann. Wenn Sie Garantie das Verhalten, dann bist du in Ordnung. Andernfalls wird der Verbraucher zu halten hat verfolgen, wo sie zuletzt gelesen, so dass er weiß, wo es neben lesen sollte.

  1. Sie müssen den Mutex in den Leser sperren, wenn der Schreiber jederzeit schriftlich beginnen kann. Stellen Sie sicher, dass der Mutex ist eine benannte man so P2 sie öffnen kann.

  2. Wenn Sie die Datei mit FileShare.ReadWrite in beiden Prozessen öffnen, können Sie es offen lassen.

In dem Leser, können Sie an den Ort suchen müssen Sie EOF treffen, bevor Sie wieder lesen kann.

Wenn Sie sind sicher, dass der Schriftsteller immer anhängt und man kann sagen, wo ein Rekord Enden (weil sie immer 10 Bytes sind zum Beispiel), und Sie können eine kleine Verzögerung akzeptieren, und der Schriftsteller schreibt immer vollständige Aufzeichnungen, die Sie tun können dies ohne mutexes und Ereignisse überhaupt. Öffnen Sie die Datei mit FileShare.ReadWrite, und in den Leser halten sucht an der gleichen Stelle und versuchen, Ihre Akte zu lesen und schlafen für eine Sekunde, wenn Sie es nicht konnte. Wenn Sie einen ganzen Datensatz lesen verwalten, haben Sie ein. Abbildung Ihre Position und Schleife aus zurück an diesen Ort zu suchen und versuchen Sie es erneut zu lesen. Dies ist eine Art, wie tail -f in Unix funktioniert.

Neben der normalen Synchronisationsfunktionen, können Sie die Dateiänderungsbenachrichtigung API unter Windows für Dateiänderungen warten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top