Auf Ereignis/Signal warten



  • Hi,

    sicher eine ganz leichte Übung:

    Ich möchte mittels WinAPI-Funktionen in einem Thread auf ein Ereignis warten, welches von einem anderen Thread aus signalisiert wird. Die Wartefunktion sollte dabei einen Timeout haben.

    Womit geht sowas?


  • Mod

    WaitForSingleObject



  • Es ist schon unglaublich, wie niedrig das fachliche Niveau hier ist. WaitForSingleObject() ist kaum geeignet, da es bei allen möglichen Zuständen (z.B. Ende des Threads mit dem gegebenen Handle) in den Signalled-State geht und nicht zwangsläufig nur dann, wenn SetEvent() aufgerufen wird. Des weiteren würdest du damit ein Laufzeitproblem bekommen, da du den Signalled-State selber immer wieder zurücksetzen müsstest:

    - WaitForSingleObject() kommt zurück
    - es gibt einen Taskswitch bei dem ein neuer Event geschickt wird
    - wieder Taskswitch zurück, du rufst ResetEvent() auf, um auch beim nächsten Durchlauf das Ereignis gemeldet zu bekommen

    Was ist jetzt passiert? Genau, es ist eine Signalisierung verloren gegangen. Einen Mutex da drum rum bauen geht auch nicht, da du den für das WaitForSingleObject() nicht sauber zurücksetzen könntest. Entweder du gerätst in einen Deadlock oder du gibst den Mutex vorher wieder frei und hast wieder das gleiche Problem wie oben beschrieben.

    Was du suchst, ist eine Conditional Variable ( http://msdn.microsoft.com/en-us/library/ms682052(v=vs.85).aspx ) nur bei der hast du wirklich eine saubere Kontrolle über die Signalisierung.

    Denker



  • Denker schrieb:

    Es ist schon unglaublich, wie niedrig das fachliche Niveau hier ist.

    Jo, das hast Du mit Deinem Beitrag eindrucksvoll nachgewiesen:
    1. Kann WaitForSingleObject auf ein mittels CreateEvent erzeugtes Event warten und kehrt dann auch nur bei Signalisierung dieses Events zurück, und nicht bei Ende irgendwelcher Threads.
    2. Gibt es auto-reset EventObjekte, die bei Rückkehr der Wait-Funktion selbsttätig wieder in den nonsignaled State zurückkehren.
    3. käme ich nicht auf die Idee, den EventReset in dem wartenden Thread zu machen, den muß der Thread durchführen, auf den gewartet werden soll - beim ersten Mal erstellt er das Event, in Folgedurchläufen resettet er es.

    Aber sonst ist alles richtig, was Du schreibst ... äh, mehr hattest Du ja gar nicht geschrieben, sorry ...



  • Belli schrieb:

    käme ich nicht auf die Idee, den EventReset in dem wartenden Thread zu machen, den muß der Thread durchführen, auf den gewartet werden soll - beim ersten Mal erstellt er das Event, in Folgedurchläufen resettet er es

    Stürzt deine Software eigentlich oft und an immer anderen Stellen ab?

    Wenn nach deiner Logik der signalisierende Thread den Event zurücksetzen soll - WANN machst du das? Wie stellst du sicher, dass der empfangende Thread schon reagiert hat? Oder machst du noch einen Rückkanal auf, in dem du meldest "jetzt kann ein Reset erfolgen"?

    ROTFL!



  • Wie ich schon bemerkte, wenn ich immer wieder auf dasselbe Event warten will, erstelle ich ein auto-reset Event.

    Wenn ich das manuell machen will, mache ich das an der Stelle, an der ich es beim ersten Mal erstelle:
    Der, auf den gewartet werden soll:

    while(1)
    {
      if(event schon erstellt)
           reset Event;
      else
         create Event;
    
      mach alles Mögliche;
    
      setz Event auf signaled;
    }
    

    oder einfach:

    while(1)
    {
      if(event noch nicht erstellt)
           create Event;
    
      mach alles Mögliche;
    
      setz Event auf signaled;
      reset Event;
    }
    

    Der, der wartet:

    while(1)
    {
       mach irgendwas;
    
       warte auf Event;
    
       mach nochwas;
    }
    

    Schwierig, nicht wahr?


  • Mod

    Denker schrieb:

    Stürzt deine Software eigentlich oft und an immer anderen Stellen ab?

    Wenn nach deiner Logik der signalisierende Thread den Event zurücksetzen soll - WANN machst du das? Wie stellst du sicher, dass der empfangende Thread schon reagiert hat? Oder machst du noch einen Rückkanal auf, in dem du meldest "jetzt kann ein Reset erfolgen"?

    ROTFL!

    Lachst Du über Dich selbst?
    Was soll diese unangemessene Polemik?

    Belli hat vollkommen recht. Bei einem Auto-Reset Event muss man sich um nichts kümmern. DerEvent wird zurückgesetzt im Wait!

    Ansonsten würde ich Dich bitten nochmal zu lesen was der OP wollte!
    Er wollte eine Funktion die wartet und ein Timeout hat. WaitForSingleObject ist immer das Mitel der Wahl. Egal ob Mutex, Semaphore odeer Event verwendet wird.
    Da er uns nicht mehr Details gibt brauche ich auch erstmal nicht mehr in seine Anfrage hineininterpretieren.


Anmelden zum Antworten