MainThread soll auf ein Workerthread warten
-
Hallo zusammen,
Ich hab mich wieder mal ans Multithreading rangewagt. Und nun möchte ich zum ersten mal ein wenig synchronisieren. Ich habe auch zahlreiche Hilfen im Inet gefunden, wie z.b. WaitForSingleObject, bzw. auch das WaitForMultiObject, CEvents usw. usf.
Nun ich habe einen MainThread (logisch) dort rufe ich mit AfxBeginThread einen neuen Thread auf. Ich speichere den Pointer CWinThread den ich zurück bekomme. Nun im Arbeitsthread kann es nun vorkommen, dass eine Message zum Mainthread gesendet wird und zwar eine WM_CLOSE. Bevor jetzt alles einfach beendet wird, soll aber der Arbeitsthread noch zuende arbeiten. Nun da ich mir eigentlich gedachte habe, dass wenn der MainThread geschlossen wird, der Arbeitsthread automatisch auch abgewürgt wird (ka ob das stimmt, aber ich nehms mal an), dachte ich, ich werde den MainThread auf den Arbeitsthread warten lassen, bis der letztere fertig ist. So habe ich die Message WM_CLOSE abgefangen.
Und in der Funktion OnClose habe ich nun ein WaitForSingleObject eingefügt, mit einem HANDLE zum Arbeitsthread und INFINITE als Parameter.Was passiert nun? Alles schläft ein! Sogar mein Arbeitsthread! Wodurch das ganze Programm schlafen geht und es nie beendet wird. Kann mir das einer erklären?
Braucht ihr noch mehr Code um das besser analysieren zu können? Oder hat jemand spontan ne Idee, welche unter die Kategorie Anfänger Fehler tritt?
Danke für die Hilfe im voraus!
Grüssli
-
Du hast vermutlich SendMessage verwendet und hast dies an den Main Thread gesendet. Die Nachricht WM_CLOSE kommt an aber Dein Main Thread returniert nie!
Also steht Dein Worker immer noch in SendMessage und wartet daruf, dass die Nachricht in Deinem Main abgearbeitet wird und der return durchgeführt wird. Nun wartest Du aber auf den Worker Thread im Main Thread, der seinerseits auf den Worker Thread wartet: Klassischer Deadlock!
Verwende PostMessage!
-
Wuhu ... Dankeschön funktioniert!
Hmmm hab ich ja noch gar nie gelesen, dass es zwei unterschiedliche gibt. Aber nützlich zu wissen ^^
Vielen Dank!
Grüssli
-
Es gibt sogar noch ein paar mehr Funktionen zum Nachrichten weiterleiten
(z.B. SendMessageCallback() - gibt dem Ziel eine Funktion an, die nach der Bearbeitung aufgerufen werden soll - oder SendMessageTimeout() - bricht nach einer Weile mit der Arbeit ab)
-
Oha ... das Thema habe ich bisher wirklich kaum angeschaut, merkt man irgendwie. *g*
Danke CStoll. Jetzt fehlt mir nur noch, wie ich benutzerdefinierte WM_Messages definieren kann ^^
Das mit dem mitschicken bei ON_COMMAND habe ich schon raus. Aber eine eigene Nachricht, wäre manchmal schon noch nützlich. Mal schauen was ich in der MSDN dazu finde ^^
Danke jedenfalls!
Grüssli
-
Definieren kannst du sie ganz einfach per
#define WM_MYMESSAGE WM_USER+x(x ist ein positiver Wert, der für jede deiner Nachrichten eindeutig sein sollte)
Den zugehörigen MessageHendler definierst du per "ON_MESSAGE(WM_MYMESSAGE,OnMyMessage)"
-
ehm? Ups da habe ich was durcheinander gebracht. Hab was anderes gemeint, was aber eigentlich nichts mit dem zu tun hat, egal ^^
Danke trotzdem.
Grüssli
-
CStoll schrieb:
Definieren kannst du sie ganz einfach per
#define WM_MYMESSAGE WM_USER+xBesser WM_APP! Wenn man nicht genau weiß auf welcher Klasse das Fenster basiert, an das man die Nachricht sendet. Wäre es z.B. ein CEditView oder ein anderes von einer Windows Fensterklasse abgeleitetes Fenster könnte das in die Hose gehen.
WM_USER sollte nur verwendet werden, wenn man selbst die Fensterklasse entwickelt um damit die privaten Fensternachrichten zu definieren.