Effizienter Consumer-Thread mit mehreren Herstellern

8

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.

    
iam 26.08.2010, 06:52
quelle

4 Antworten

2

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:

  • Das Ereignis ist ein Ereignis zum manuellen Zurücksetzen.
  • Die durch den kritischen Abschnitt geschützten Vorgänge sind schnell. Das Ereignis wird nur gesetzt oder zurückgesetzt, wenn die Warteschlange in den leeren Zustand übergeht. Es muss innerhalb des kritischen Bereichs gesetzt / zurückgesetzt werden, um eine Wettlaufsituation zu vermeiden.
  • Dies bedeutet, dass der kritische Abschnitt nur für kurze Zeit gehalten wird. so wird Konkurrenz selten sein.
  • Kritische Abschnitte werden nur blockiert, wenn sie angefochten werden. Daher werden Kontextwechsel selten sein.

Annahmen:

  • Das ist ein echtes Problem, keine Hausaufgaben.
  • Hersteller und Verbraucher verbringen die meiste Zeit damit, andere Dinge zu tun, d. h. die Artikel für die Warteschlange bereit zu machen und sie nach dem Entfernen aus der Warteschlange zu verarbeiten.
  • Wenn sie die meiste Zeit mit den eigentlichen Warteschlangenoperationen verbringen, sollten Sie keine Warteschlange verwenden. Ich hoffe, das ist offensichtlich.
Ben 03.03.2011 17:37
quelle
0

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.

    
Dave Dunn 05.10.2010 21:54
quelle
0

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

%Vor%

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.

    
Anthony Williams 08.10.2010 10:46
quelle
0

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.

    
Marcel 02.12.2010 11:42
quelle