Ich versuche, eine Producer / Consumer-Thread-Situation effizienter zu machen, indem ich teure Event-Operationen bei Bedarf auslassen kann, etwa mit:
%Vor%Offensichtlich ist es etwas schwierig, diese Dinge richtig zu machen (!), also ist der obige Pseudocode korrekt? Eine Lösung, die das Ereignis mehr als genau benötigt, ist in Ordnung, aber nicht für jedes Element.
Dies fällt in die Unterkategorie "Hör auf, herumzuspielen und zur Arbeit zurückzukehren", die als "vorzeitige Optimierung" bezeichnet wird. : -)
Wenn die "kostspieligen" Ereignisoperationen einen beträchtlichen Teil der Zeit beanspruchen, ist Ihr Design falsch, und anstatt einen Produzenten / Verbraucher zu verwenden, sollten Sie einen kritischen Abschnitt / Mutex verwenden und nur die Arbeit des aufrufenden Threads ausführen.
Ich schlage vor, Sie profilieren Ihre Anwendung, wenn Sie wirklich besorgt sind.
Aktualisiert:
Richtige Antwort:
Produzent
%Vor%Verbraucher
%Vor%Anmerkungen:
Annahmen:
Durch eine Reihe von Fällen gegangen, kann kein Problem sehen. Aber es ist irgendwie kompliziert. Ich dachte, du könntest vielleicht ein Problem mit queue_not_empty / add_to_queue haben. Sieht aber so aus, als ob der post-dominierende CAS in beiden Fällen diesen Fall abdeckt.
CAS ist teuer (nicht so teuer wie Signal). Wenn Sie erwarten, das Signal zu überspringen, würde ich das CAS wie folgt codieren:
%Vor%Lock-free-Strukturen wie diese sind die Dinge, die Jinx (das Produkt, an dem ich arbeite) sehr gut testen kann.
Vielleicht möchten Sie eine Evaluierungslizenz verwenden, um die Logik für die blockierungsfreie Warteschlange und die Signaloptimierung zu testen.
Edit: vielleicht können Sie diese Logik vereinfachen.
%Vor%Jetzt, da das Signal cas immer nebeneinander steht, können sie in ein Unterprogramm verschoben werden.
Warum verbindest du nicht einfach ein bool
mit dem Event? Verwenden Sie cas
, um es auf "true" festzulegen, und wenn% code_% erfolgreich ist, signalisieren Sie das Ereignis, da das Ereignis gelöscht sein muss. Der Kellner kann dann einfach die Flagge löschen, bevor er wartet
Auf diese Weise warten Sie nur, wenn sich keine Elemente in der Warteschlange befinden, und Sie signalisieren das Ereignis nur einmal für jeden Posten.
Ich glaube, Sie möchten etwas in dieser Frage erreichen:
WinForms Multithreading: Führen Sie ein GUI-Update nur durch, wenn das vorherige beendet ist. Es ist spezifisch für C # und Winforms, aber die Struktur kann gut für Sie gelten.
Tags und Links multithreading thread-safety producer-consumer