2010-12-31 3 views
2

Ich schreibe eine diskrete Simulation, bei der Anforderungswerte von mehreren Threads in einer zentralen Warteschlange gesammelt werden. Alle n Millisekunden wacht ein Manager auf, um Anforderungen zu verarbeiten. Wenn der Manager aufwacht, sollte er alle des Inhalts der zentralen Warteschlange in einem einzelnen diskreten Schritt abrufen. Bei der Verarbeitung sollten alle Client-Threads, die versuchen, an die Warteschlange zu senden, blockiert werden. Wenn die Verarbeitung abgeschlossen ist, wird die Warteschlange wieder geöffnet, und der Manager wechselt wieder in den Ruhezustand.Entfernen des Inhalts eines Chan oder MVar in einem einzelnen separaten Schritt

Was ist der beste Weg, dies zu tun? Das Wiederholungsverhalten von STM ist nicht das, was ich möchte. Wenn ich einen Chan oder MVar verwende, gibt es keine Möglichkeit zu verhindern, dass Clients während der Verarbeitung zusätzliche Anfragen in die Warteschlange stellen. Ein Ansatz besteht darin, einen MVar als Mutex auf einem Chan zu verwenden, der die Warteschlange hält. Gibt es andere Möglichkeiten, dies zu tun?

Antwort

5

Ich müsste unter Ihren erwarteten Wettbewerbsniveaus Benchmark, um genau zu wissen, was die beste Lösung ist, aber hier ist meine Vermutung.

Verwenden Sie eine MVar mit [Item], was auch immer Ihr Elementtyp ist. Initialisieren Sie die MVar mit newMVar []. Um ein Element zur zentralen Liste hinzuzufügen, verwenden Sie modifyMVar_ (return . (item :)), wobei item das ist, was Sie der Liste hinzufügen. Verwenden Sie takeMVar zu Beginn des Verarbeitungsdurchlaufs und putMVar [] und das Ende davon.

Beachten Sie zuerst, dass dies intern keine Warteschlange ist. Wenn Sie die Dinge in der Reihenfolge bearbeiten möchten, in der sie hinzugefügt wurden, geben Sie nach dem Extrahieren die Liste reverse ein.

Zweitens, solange dies die einzigen Vorgänge sind, die Sie an der MVar durchführen, ist dies frei von Rennbedingungen. Das ist, weil die MVar voll initialisiert wird, und jede Operation ist "nehmen Sie den Inhalt der MVar, etwas anderes hinein." Operationen können blockieren, während auf den letzten Teil davon gewartet wird, aber dies kann nicht blockiert werden und es wird keine verlorenen Aktualisierungen geben.

+0

Oh, Sie können die "Rückseite" vermeiden und die Dinge in der Reihenfolge des Einfügens halten, indem Sie einen etwas komplizierteren Typ innerhalb der 'MVar' verwenden. Ich habe das weggelassen, weil ich es nicht für nötig halte, meine Antwort zu komplizieren. Aber es ist machbar, wenn Sie das wollen. – Carl

1

Gibt es nicht ein Problem mit MVar [a] obwohl? Wenn es keine zu lesenden Objekte gibt, möchten wir, dass die Leser blockiert werden, aber da die MVar tatsächlich [] enthält, geschieht dies nicht.

+0

In diesem Fall werden wir die leere Liste auslesen, entscheiden, dass es keine Arbeit zu tun gibt und für weitere n Millisekunden aussetzen (schlafen). Dies reduziert die Abfrage nach neuer Arbeit alle n Millisekunden auf nicht weniger. –

Verwandte Themen