Timer, Thread und Mutex

Thomasio

Erfahrenes Mitglied
Ich habe offensichtlich irgendetwas zum Thema Mutex nicht verstanden, vielleicht kann mich jemand aufklären, was ich damit falsch mache?
Ich habe den Code so weit gekürzt, dass nur noch der Fehler übrig bleibt.

Code:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int nCmdShow)
{

// CreateWindow usw.

CreateMutex(0,0,"SomeUniqueText");

DWORD nThreadID;
CreateThread(0,0,MyThread,0,0,&nThreadID);

// MessageLoop

}

LRESULT CALLBACK MainWindow(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{

static const UINT Timer1 = 1;

switch(msg)
{

case WM_CREATE:
{

SetTimer(hWnd,Timer1,1000,0);

return 0;

}
break;

case WM_TIMER:
{

KillTimer(hWnd,Timer1);

HANDLE hMutex = OpenMutex(SYNCHRONIZE,0,"SomeUniqueText");
WaitForSingleObject(hMutex,INFINITE);

// DoSomething

ReleaseMutex(hMutex);
CloseHandle(hMutex);

SetTimer(hWnd,Timer1,1000,0);

return 0;

}
break;

}
return DefWindowProc(hWnd,msg,wParam,lParam);
}

DWORD WINAPI MyThread(LPVOID data)
{

while(1)
{

HANDLE hMutex = OpenMutex(SYNCHRONIZE,0,"SomeUniqueText");
WaitForSingleObject(hMutex,INFINITE);

// DoSomething

ReleaseMutex(hMutex);
CloseHandle(hMutex);

Sleep(10000);

}

return 0;

}

Das Programm hängt sich immer dann auf, wenn MyThread den Mutex offen hat während WM_TIMER WaitForSingleObject() aufruft.
Nach meinem Verständnis müsste in dem Fall MyThread sein DoSomething beenden, den Mutex freigeben, dann müsste WM_TIMER den Mutex bekommen und seine Arbeit tun, aber stattdessen hängt das Ganze in einem deadlock und ich verstehe nicht, warum?
 
Hallo,

meines Erachtens passt der Teil mit dem Holen des Mutex nicht. OpenMutex solltest du nicht verwenden. Ich denke, dass es so aussehen müsste:
C++:
HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);

....

if( WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0 ) // Mutex-Zugriff
{ 
    // DoSomething
    
    ReleaseMutex(hMutex);  // freigeben
}


Allerdings ist es für Thread-Synchronisation performanter, CriticalSection zu verwenden. Du kannst dir ja auch mal die API-Funktionen InitializeCriticalSection(), EnterCriticalSection() und LeaveCriticalSection() anschauen.

Gruß
MCoder
 
Hi MCoder,

CreateMutex() steht im WinMain, sprich der Mutex bleibt für die gesamte runtime erhalten.
Zur Synchronisierung brauche ich schon OpenMutex(), denn CreateMutex() kennt keine SYNCHRONIZE Option. (oder doch?)

CriticalSection() habe ich mir schon mehrmals angeschaut, aber nie auf die Reihe bekommen.
Ich weiss nicht, ob es Anderen auch so geht, aber MSDN ist für mich nur bedingt hilfreich, da finde ich zwar die passenden API Funktionen, aber die Codebeispiele die sie dort haben sind mir zu hoch.
Ich suche mir dann meistens irgendwo anders ein einfacheres Codebeispiel, nur zu CriticalSection habe ich anderweitig nichts gefunden.

Den Wait in ein if verpacken muss ich mal probieren, vielleicht nutzt es was.
Auf jeden Fall vielen Dank für die Antwort.
 
Hi.
CreateMutex() steht im WinMain, sprich der Mutex bleibt für die gesamte runtime erhalten.
Du rufst dort aber CloseHandle auf, und das System zerstört den Mutex wenn keine Referenzen darauf mehr existieren. (siehe MSDN)
Zur Synchronisierung brauche ich schon OpenMutex(), denn CreateMutex() kennt keine SYNCHRONIZE Option. (oder doch?)
Benannte Mutexe brauchst du grundsätzlich nur zur Interprozeßkommunikation.

Innerhalb eines Prozesses brauchst du auch keine Zugriffsrechte angeben, die SYNCHRONIZE Option ist also überflüssig.
CriticalSection() habe ich mir schon mehrmals angeschaut, aber nie auf die Reihe bekommen.
Was ist denn so schwierig daran?
Ich weiss nicht, ob es Anderen auch so geht, aber MSDN ist für mich nur bedingt hilfreich, da finde ich zwar die passenden API Funktionen, aber die Codebeispiele die sie dort haben sind mir zu hoch.
Ich finde das MSDN eigentlich ziemlich gut. Es gibt auch ein einfaches Beispiel für Mutexes: http://msdn.microsoft.com/en-us/library/ms686927(v=vs.85).aspx

Grundsätzlich solltest du immer Rückgabewerte von Funktionen prüfen, es könnte ja sein, das die Funktion fehl schlägt... ?! :eek:

Gruß
 
Das Wichtigste zuerst: Ich habe meinen Fehler gefunden, ein blödsinniger Tippfehler.

Nach euren Anmerkungen werde ich mir CriticalSection doch nochmal zu Gemüte führen, auch wenn die Signatur von deepthroat sagt ich sollte es lassen, vielleicht bekomme ich es im 25ten Anlauf auf die Reihe.

Ich danke euch beiden.
 

Neue Beiträge

Zurück