2009-03-13 5 views
0

Ich benutze eine Anwendung, bei der eine Anwendung der unteren Ebene immer einen Callback RecData (char * buf) aufruft, wenn sie Daten empfängt.Wie benutze ich eine Warteschlange mit zwei Threads - eine für Consumer und eine für Producer

Im Callback erstelle ich zwei Threads und übergebe die Consumer- und Producer-Funktion an diese erzeugten Threads.

Mein Code:

Leere RecData (char * buf) {

CreateThread(NULL,0,producer_queue,(void *)buf,0,NULL); 
CreateThread(NULL,0,consumer_queue,NULL,0,NULL); 

}

Die oben genannten Arbeiten, wenn ich ein Datum zu einem Zeitpunkt erhalten. Wenn ich ungefähr 5 Daten fast gleichzeitig bekomme, dann sollte producer_queue zuerst alle Daten in die Warteschlange stellen und dann consumer_queue sollte mit dem Abrufen der Daten beginnen, aber hier, sobald producer_queue die ersten Daten in die Warteschlange legt, ruft consumer_queue sie ab.

+0

Gibt es einen Grund, warum Sie jedes Mal, wenn Sie Daten empfangen, 2 Threads spawnen? – Alan

+0

NEIN mein einziges Motiv ist das Einreihen der Daten in die Warteschlange und das Lesen der Daten aus der Warteschlange, aber wenn ich nur einen Thread für den Producer in die RecData (char * buf) -Funktion lege, wie und wann werde ich anfangen, die Daten aus der Warteschlange zu lesen. bitte help –

+0

Ein anderer Ansatz könnte sein, einen einzelnen Leser-Thread zu spawnen. In der RecCall zurück, würden Sie nur die Warteschlange sperren und die Daten in die Warteschlange stellen.Ihr Reader-Thread würde eine Schleife zum Lesen der Daten aus der Warteschlange ausführen. Nur ein Gedanke. – Alan

Antwort

1

Was Sie tun möchten, glaube ich, ist die Kontrolle Zugriff auf die Warteschlange. Sie sollten einen Mutex verwenden, um das Lesen aus der Warteschlange zu steuern.

Wenn Sie Daten empfangen, werden Sie den Mutex sperren und dann die Daten in die Warteschlange stellen. Wenn Sie mit dem Einreihen der Daten fertig sind, geben Sie die Sperre frei.

Beim Lesen aus der Warteschlange sehen Sie, ob der Mutex gesperrt ist. Wenn Sie Daten in die Warteschlange schreiben, können Sie nicht mit dem Lesen beginnen, bis Ihr Produzententhread alle Daten geschrieben und die Sperre aufgehoben hat. Wenn Sie den Mutex tatsächlich sperren, verhindern Sie, dass der Writer-Thread schreibt, während Sie Daten lesen.

Dieser Ansatz könnte potenzielle Deadlocks einführen. Wenn Ihr Writer-Thread vor dem Aufheben der Sperre abstirbt, kann Ihr Reader-Thread nicht fortfahren (dann kann Ihr Threading-Thread erneut einen Fehlerstatus auslösen).

Ich hoffe, das macht Sinn.

+0

Hallo Alan, Was passiert eigentlich mit dem obigen Code, den ich in meinem Ques erwähnt, ist dieser Thread für den Hersteller und den Thread für die Verbraucher werden immer nacheinander erstellt. –

+0

Sagen Sie, wenn der RecData (char * buf) -Rückruf fast gleichzeitig 5 Daten empfängt, dann zum Schreiben der ersten Daten in der Warteschlange, erzeugt er einen Thread für den Produzenten, der ihn in die Warteschlange schreibt, und dann erstellt er einen weiteren Thread (Consumer) um die Daten zu lesen und das Gleiche passiert auch für die nächsten Daten. –

+0

Ich möchte, dass es sich verhält, wenn es 5 Daten empfängt, der Produzent sollte alle 5 Daten in die Warteschlange schreiben und dann sollte der Verbraucher-Thread anfangen, diese 5 Daten aus der Warteschlange zu lesen. Ist es möglich? Danke –

0

Verwenden Sie das Konzept der Bedingungsvariablen. Das Problem, das Sie haben, ist das häufigste in der Multi-Thread Programmierwelt. Die Verwendung von Mutexen hilft der Situation nicht. Denken Sie immer daran, dass Mutexe zum Sperren sind & Zustandsvariablen sind zum Warten. Letzteres ist immer sicherer und fast sicher, wenn ein Thread beginnen sollte, aus einer gemeinsamen Warteschlange zu konsumieren.

Schauen Sie sich den folgenden Link auf, wie Sie eine Zustandsgröße auf eigene Faust auf Windows erstellen können: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html

Wenn Sie Windows Vista verwenden, können die folgenden Msdn Beispiel helfen Ihnen: http://msdn.microsoft.com/en-us/library/ms686903(VS.85).aspx

In allen Fällen verwenden Sie die Logik, wie sie auf der Website von Schmidt angezeigt wird, da sie tragbarer aussieht (oh ja auf verschiedene Versionen von Windows atleast übertragbar). Die Implementierung von Schmidt bietet Ihnen das Standard-POSIX-API, das auf den meisten modernen UNIX/LINUX-Systemen weit verbreitet ist.

+0

Ihr msdn Link ist ein wenig ausgebrockt. –

Verwandte Themen