Auf Mutex-ownership warten ohne Sleep()?
-
@Exclud0r:
int main() { HANDLE mutex = ::CreateMutex(0, false, _T("{17E7683D-20D4-4f81-B2C4-6969797F11EA}")); if (mutex == 0) { Fehler(); return 3; } DWORD waitResult = ::WaitForSingleObject(mutex, INFINITE); if (waitResult == WAIT_OBJECT_0) { // mutex gehört nun uns, alles gut, weitermachen } else if (waitResult == WAIT_ABANDONED) { // der andere Prozess wurde beendet, ohne die Mutex freizugeben // ggf. vorher aufräumen (TEMP Files, was auch immer), und dann weitermachen } else { Fehler(); return 3; } // Mutex gehört nun uns DoStuff(); ::ReleaseMutex(mutex); // Mutex "entsperren" // nächstes Programm läuft *jetzt* los ::CloseHandle(mutex); // Mutex handle freigeben return 0; // fertig }
-
Mutex-Objekte können verschiedene Prozesse synchronisieren, was Du ja willst. Sleep hat da absolut nichts zu suchen! Ein Mutex-Ownership beanspruchen und sofort wieder freigeben ist unsinnig. Freigeben sollte immer ein anderer Prozess. Das ist der Sinn von Mutex-Objekten. WaitForSingleObject macht dafür die Synchronisation und das sehr gut. Du musst einfach mal in den Beschreibungen der WinApi nachlesen und dann machen! daddeldu
-
Ah, super, danke @hustbaer, funktioniert.
Habe es auch mit WaitForSingleObject probiert, aber irgendwas hat da nicht geklappt.
Aber das Handle ist doch laut MSDN signaled, wenn ein Thread ownership hat, warum kehrt die Wait-Funktion nicht gleich zurück?
-
@berniebutt
Beschreibungen... siehe letzte Frage @mein voriger Post.Ja, mein Code war nur zum testen. Und freigeben soll in meinem Fall nicht ein anderer Prozess, denn es geht mir, wie schon ganz am Anfang beschrieben, darum, dass immer nur eine Instanz eines Programmes arbeitet, während weitere erstellte Instanzen warten müssen.
-
Auch eine andere Instanz eines Programmes ist ein anderer Prozess. Wenn eine Instanz das Mutex beansprucht bleiben alle neuen Instanzen geblockt.
-
Ich kapier nicht, was du mir damit sagen willst.
-
Für Deine Frage sind Mutex-Objekte grundsätzlich bestens geeignet. Wenn Du mich oder andere nicht verstehst, dann fehlt Dir etwas Wissen über Prozesse, Instanzen und ähnliches. Ich hatte gesagt: Sleep gehört da definitiv nicht hin und ReleaseMutex gibt frei. Wo ist denn nun Dein Problem? Ich verstehe es nicht.
-
Exclud0r schrieb:
Ah, super, danke @hustbaer, funktioniert.
Habe es auch mit WaitForSingleObject probiert, aber irgendwas hat da nicht geklappt.
Aber das Handle ist doch laut MSDN signaled, wenn ein Thread ownership hat, warum kehrt die Wait-Funktion nicht gleich zurück?Der Zustand ist "signaled" wenn kein Thread "ownership" hat.
Und WaitForSingleObject ist so implementiert, dass der "signaled" Zustand sofort auf "non-signaled" geändert wird, und als "owner" der aktuelle Thread eingetragen, bevor WaitForSingleObject mit "WAIT_OBJECT_0" zurückkehrt.Steht in der MSDN alles beschrieben, lesen müsste man halt können.
MSDN schrieb:
The state of a mutex object is signaled when it is not owned by any thread. The creating thread can use the bInitialOwner flag to request immediate ownership of the mutex. Otherwise, a thread must use one of the wait functions to request ownership. When the mutex's state is signaled, one waiting thread is granted ownership, the mutex's state changes to nonsignaled, and the wait function returns. Only one thread can own a mutex at any given time. The owning thread uses the ReleaseMutex function to release its ownership.
-
Ich Dumpfbacke, hab genau das verwechselt.
Ah, jetzt macht es Sinn.
(Ich habe einfach nicht glauben _wollen_, dass die Wait-Funktion mehr als nur Warten macht, deshalb hab ich den Satz nicht verstanden)Nun, aber eines macht mir noch Sorgen:
Laut MSDN: Wenn das Handle geschlossen wird, während noch gewartet wird, ist das Verhalten der Wait-Funktion undefiniert.::ReleaseMutex(mutex); // Mutex "entsperren" // nächstes Programm läuft *jetzt* los ::CloseHandle(mutex); // Mutex handle freigebenKönnte es da nicht zu einem UB kommen? Es wird zwar zuerst released, aber wenn aus irgendeinem Grund die Wait-Funktion einer weiteren Instanz nicht gleich dazukommt, den ownership zu requesten, und das Handle nun geschlossen wird ...?
Oder kann das garnicht passieren?Hachja, Windows Windows...
-
Ah, ich denke, ich verstehe.
Da in jeder Instanz vor der Wait-Funktion CreateMutex() aufgerufen wird, wird damit ein weiteres Handle geholt, somit gibt es auch kein UB.
-
Genau.
Kann eigentlich nur schief gehen, wenn du aus einem 2. Thread (im selben Prozess), das Handle schliessen würdest, während der erste Thread in WaitForSingleObject wartet. Da muss man sich schon ziemlich dumm anstellen um das zu schaffen