ReleaseMutex geht nicht ((((

july

Erfahrenes Mitglied
Hallo zusammen,

ich habe 3 Threads, die parallel laufen sollen.
C++:
DWORD WINAPI receive_thread(LPVOID attr);
DWORD WINAPI update(LPVOID attr);

HANDLE mutex, anzmutex;
HANDLE events[2];

int main(){
...
  HANDLE h, hanz;
  static HANDLE stdinHandle;
  mutex = CreateMutex(NULL,FALSE , NULL); // steht frei
  anzmutex = CreateMutex(NULL, TRUE, NULL); // ist geblockt
  stdinHandle = GetStdHandle(STD_INPUT_HANDLE); //handle für die Eingabe
  events[0] = anzmutex;
  events[1] = stdinHandle;
...
 hanz = CreateThread(NULL, 0, update, (LPVOID) &aAttr, 0, NULL);
//Aufbau der Connection mit winsock
while(1)
{
//wenn neue Connection kommt
h = CreateThread(NULL, 0, receive_thread, (LPVOID) &attr,
                          0, NULL);
...
}
return 0;
}

DWORD WINAPI receive_thread(LPVOID attr)
{....
 if (WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0)
        {
          msgid = pmap->addMessage(msg.meldung); //Schreibvorgang muss geschützt werden
          ReleaseMutex(mutex);
        }
...
 ReleaseMutex(anzmutex); //genau diese Zeile geht iwie nicht;
  return (0);

}

DWORD WINAPI update(LPVOID attr)
{
 DWORD changeEvent;
....
while(1)
{
//macht eine Ausgabe von dem aktuellen Zustand des Meldungsspeichers mit printf's
if(meldungscounter>0){
changeEvent = WaitForMultipleObjects(2, events, FALSE, INFINITE);
 switch (changeEvent)
            {
          case WAIT_OBJECT_0 + 0: //es wurde eine neue Meldung eingetragen
            {
              break;
            }
          case WAIT_OBJECT_0 + 1: //es gab eine Konsoleneingabe
            {
              cin >> eingabe;
              if (eingabe > 0 && eingabe <= 7)
                {
                  choice = eingabe;
                }
              break;
            }
            }
}
else
{
          WaitForSingleObject(anzmutex, INFINITE); //funktionniert nicht, bzw kommt hier nie raus
          choice = 0;
}
...
}
}


Also in den receive_thread kommt er rein, Releasemutex wird angeblich auchgemacht, bloss in dem update_thread wird aus dem blockierenden Zustand nicht rausgegangen.
Habt ihr eine Idee woran es liegt?

Grüße July
 
Zuletzt bearbeitet von einem Moderator:
Hi

Da sind ein paar wichtige Codestellen ausgelassen.

Nur so geraten: Warum ist es im receive_thread zuerst mutex, dann anzmutex?
 
@sheel
weil mit mutex die schreibvorgänge geschützt werden und anzmutex sagt dem update thread bescheid, dass was sich verändert hat und die Anzige darf sich nochmal darstellen. Update-Thread läuft in while(1)-Schleife.

Hab noch paar Kommentare im Code geaddet, vielleicht hilft das.

Grüße July
 
Zuletzt bearbeitet:
Hi.

Was heißt denn "es geht nicht"? Wie ist der Rückgabewert der ReleaseMutex Funktion? Welchen Wert liefert GetLastError?

Man kann einen Mutex nur freigeben, wenn man ihn vorher in Besitz genommen hat. Der anzmutex wird vom main-Thread besessen, ist also nie vom receive-Thread in Besitz genommen worden.

Wenn du dem Thread nur ein kurzes Signal geben willst, verwende doch einen Event. Oder schau mal hier: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html

Gruß
 
Was heißt denn "es geht nicht"? Wie ist der Rückgabewert der ReleaseMutex Funktion? Welchen Wert liefert GetLastError?
Das heisst es läuft ohne Fehlermeldung durch, aber in dem update-thread wird der blockierende Zustand nicht verlassen.
Man kann einen Mutex nur freigeben, wenn man ihn vorher in Besitz genommen hat. Der anzmutex wird vom main-Thread besessen, ist also nie vom receive-Thread in Besitz genommen worden.
heißt das, dass ich in jedem Thread, der den Mutex benutzt, einen CreateMutex machen soll?

Grüße July
 
Das heisst es läuft ohne Fehlermeldung durch, aber in dem update-thread wird der blockierende Zustand nicht verlassen.
Wo sollen denn die Fehlermeldungen herkommen? Du hast den Rückgabewert von ReleaseMutex doch gar nicht geprüft und GetLastError hast du auch nicht benutzt...
heißt das, dass ich in jedem Thread, der den Mutex benutzt, einen CreateMutex machen soll?
Quatsch. Das macht überhaupt keinen Sinn. Einen Mutex nimmt man mit WaitForXXXObject in Besitz.

Wozu soll denn der anzmutex gut sein? So wie es aussieht willst du da nur einmal eine Zustandsänderung signalisieren.

Gruß
 
Wo sollen denn die Fehlermeldungen herkommen? Du hast den Rückgabewert von ReleaseMutex doch gar nicht geprüft und GetLastError hast du auch nicht benutzt...
Doch hab jetzt auspriobiert
C++:
if(ReleaseMutex(anzmutex)==0)
    {
      cout << "Fehler bei Releasemutex: " << GetLastError();
    }
Wozu soll denn der anzmutex gut sein? So wie es aussieht willst du da nur einmal eine Zustandsänderung signalisieren.
es wird nicht nur ein mal signaliesiert, sondern jedes mal wenn eine neue Connection kommt (siehe Main-thread), und anzmutex wird im update-Thread mit WaitForXXXObject blockiert.
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

Für das Signalisieren von Zustandsänderungen solltest du eigentlich Events und keine Mutex verwenden. Der Vorteil von Events liegt genau darin, das ein Mutex immer von einem Thread in Besitz genommen wird, und ein Event nicht.
 
Hallo,

ich hab jetzt mit Event versucht das ganze zu lösen. Ergebniss: Beim ersten mal signaliesiert es 1A, aber beim 2.mal kommt nix an. Die nächste Nachrichten werden angeblich synchronisiert, es kommt keine Fehlermeldung, aber WaiitForXXXObject() wird nicht verlassen :(
C++:
int main()
{
....  
  mutex = CreateMutex(NULL,FALSE , NULL); // steht frei
  anzevent = CreateEvent(NULL,TRUE,FALSE,TEXT("Neue Meldung eingetrofen"));
  stdinHandle = GetStdHandle(STD_INPUT_HANDLE); //handle für die Eingabe
  events[0] = anzevent;
  events[1] = stdinHandle;
...
}
DWORD WINAPI receive_thread(LPVOID attr)
{
 ...
 if (WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0)
        {
          msgid = pmap->addMessage(msg.meldung); //Schreibvorgang muss geschützt werden
          ReleaseMutex(mutex);
        }
....
  if(PulseEvent(anzevent)== 0)
    {
      cout << "Das Eintreffen der neuen Meldung konnte nicht signalisiert werden: " << GetLastError();
    }
}
DWORD WINAPI update(LPVOID attr) // hier musste ich nichts ändern
{
DWORD changeEvent;
....
while(1)
{
//macht eine Ausgabe von dem aktuellen Zustand des Meldungsspeichers mit printf's
if(meldungscounter>0){
changeEvent = WaitForMultipleObjects(2, events, FALSE, INFINITE);
 switch (changeEvent)
            {
          case WAIT_OBJECT_0 + 0: //es wurde eine neue Meldung eingetragen
            {
              break;
            }
          case WAIT_OBJECT_0 + 1: //es gab eine Konsoleneingabe
            {
              cin >> eingabe;
              if (eingabe > 0 && eingabe <= 7)
                {
                  choice = eingabe;
                }
              break;
            }
            }
}
else
{
          WaitForSingleObject(anzevent, INFINITE); //funktionniert nicht, bzw kommt hier nie raus
          choice = 0;
}
...
}
}
 
Zuletzt bearbeitet von einem Moderator:
Zurück