Wann ist ein Thread suspendiert?



  • Tut mir leid, dass ich in den falschen Forum geschrieben habe.

    Danke werde mir das gleich anschauen 🙂



  • Ich glaube jetzt das Prinzip verstanden zu haben, habe auch einen kleinen Test geschrieben jedoch funktioniert das irgend wie nicht hier der Codeausschnitt:

    DWORD WINAPI execute(LPVOID data)
    {
    	while (true) {
    		// mache was ...
    		WaitForSingleObject(*((HANDLE*)data),INFINITE);
    		// der Rückgabewert ist WAIT_FAILED
    		// und der ErrorCode ist ERROR_INVALID_HANDLE
    	}
    	return 0;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HANDLE thread;
    	DWORD threadID;
    	HANDLE _event;
    
    	_event = CreateEvent(NULL,TRUE,FALSE,NULL);
    	SetEvent(_event);
    	thread = CreateThread(NULL,0,execute,&_event,0,&threadID);
    	CloseHandle(thread);
    	CloseHandle(_event);
    
    	getchar();
    	return 0;
    }
    

    Weis vielleicht einer warum das so ist?



  • das sollte so aussehen:

    thread = CreateThread(NULL,0,execute,&_event,0,&threadID);
    Sleep(1);    
    CloseHandle(thread);
    

    Ok das war ein dummer Fehler, vielen dank für die Hilfe.



  • Eher sollte es so aussehene:

    int _tmain()
    {
      // ...
      thread = CreateThread(NULL,0,execute,&_event,0,&threadID);
      WaitForSingleObject(thread, INFINITE);
      CloseHandle(thread);
    }
    

    Sonst wird Dein Programm sofort wieder beendet, da die CRT beim verlassen der "main" ExitProcess" aufruft...



  • stimmt, danke 🙂



  • Jochen Kalmbach schrieb:

    Wie "tipp" gesagt hat, solltest Du *niemals* SuspendThread aufrufen. SOndern wie "ajsipo" empfohlen hat korrekte Synchronisations-Funktionen.

    Warum man nie SuspendThread aufrufen sollte, kannst Du hier nachlesen:
    http://blog.kalmbachnet.de/?postid=6
    (unt weitere Blog-Einträge von mir)

    Oh Mann! Das Thema von wegen nie TerminateThread/SuspendThread benutzen hatten wir schon mal!
    Wieso nie TerminateThread?? Da hätet ich gerne eine einleuchtende Begründung!

    EDIT: Außerdem Dead-Locked dein Beispiel bei mir noch nicht einmal 👎

    EDIT:

    Jochen Kalmbach schrieb:

    Eher sollte es so aussehene:

    int _tmain()
    {
      // ...
      thread = CreateThread(NULL,0,execute,&_event,0,&threadID);
      WaitForSingleObject(thread, INFINITE);
      CloseHandle(thread);
    }
    
    DWORD WINAPI execute( void* )
    {
        while ( 1 )
            ;
    }
    
    int main( ... )
    {
      DWORD threadID;
      HANDLE thread = CreateThread(NULL,0,execute,0,0,&threadID);
      WaitForSingleObject(thread, INFINITE);
      CloseHandle(thread);
    }
    

    Ist bei mir auch ein Deadlock ⚠



  • Badestrand schrieb:

    Wieso nie TerminateThread?? Da hätet ich gerne eine einleuchtende Begründung!
    EDIT: Außerdem Dead-Locked dein Beispiel bei mir noch nicht einmal 👎

    Begründungen hab ich genügend geschrieben, musst nur lesen...

    Und was soll bei dem Beispiel nicht "gehen"? Natürlich geht es nicht... das war es ja was ich zeigen wollte.



  • Badestrand schrieb:

    DWORD WINAPI execute( void* )
    {
        while ( 1 )
            ;
    }
    int main( ... )
    {
      DWORD threadID;
      HANDLE thread = CreateThread(NULL,0,execute,0,0,&threadID);
      WaitForSingleObject(thread, INFINITE);
      CloseHandle(thread);
    }
    

    Ist bei mir auch ein Deadlock ⚠

    Das ist kein Dead-Lock sondern beabsichtigter Code (hier ist nicht gegenseitig gelockt...) Auch wenn der Code etwas sinnfrei ist... wenn aber die "main" sofort zurückkehrt, beendet sich bei der CRT der gesamte Prozess...



  • Tut mir Leid, wenn mein Post vorhin etwas unfreundlich klang. War zwar auch so gemeint, hatte aber einfach schlechte Laune => Sorry!

    Was ich nur meinte:
    Ich erkenne bei deinem Beispiel nur nicht die Gefährlichkeit, bzw. wo da der Dead-Lock sein soll. Meinem Code kann ich eine gewisse Sinnfreiheit sicherlich nicht absprechen.
    Aber dein Codebeispiel schien bei mir seine Aufgabe zu erfüllen: Abwechselnd t's und Punkte. Die t's während der Thread nicht suspended ist und die Punkte in der Zeit, wo doch. Also: Wo ist der Dead-Lock?
    Ein Dead-Lock scheint ja zu sein, wenn sich beide Threads gegenseitig "behindern". Aber sobald eine der beiden Threads aus seiner while(1)-Schleife rausgeht, passt doch alles. Könntest du das erklären?

    Zum Problem als solchem (zu TerminateThread):
    Ich selber rechne immer zu einer geringen Wahrscheinlichkeit (<0.0001%) damit, dass es sein könnte, dass irgendwelche Funktionen, und seien es welche aus der Win-API, hängenbleiben.
    Wenn ich jetzt, was dein Vorschlag ist, WaitForSingleObject( hThread, INFINITE ) benutze und eine Funktion hängenbleibt, bleibt auch mein Programm hängen (was Datenverluste zur Folge haben kann!).
    Da (so wie ich das verstanden habe) ein TerminateThread keine exorbitanten Folgen haben kann, benutze ich lieber ein solches Konstrukt:

    if ( WAIT_TIMEOUT == WaitForSingleObject( hThread, 10000 ) )
        TerminateThread( hThread, 0 );
    

    Wenn mein lieber Onkel Thread nämlich irgendwo (aus welchen Gründen auch immer!!) hängenbleiben sollte, lässt sich immerhin noch das Programm fortführen. Was für mich ein wichtiger Grund ist, weiterhin TerminateThread zu benutzen!

    EDIT: Wäre mein (sinnfreies Beispiel, siehe 2 Posts weiter oben) nicht auch ein Dead-Lock? Thread return't nicht und der Hauptthread fährt nicht fort, solange der Thread nicht fertig ist!??



  • Badestrand schrieb:

    Wo ist der Dead-Lock?

    Das hab ich ja gemeint: Es ist (für einen Laien) nicht ersichtlich wo hier der Dead-Lock sein soll. Aber wenn Du es mit MS VC++ kompilierst und es laufen lässt wirst Du nach einigen ms feststellen, dass sich das ganze aufhängt...

    Badestrand schrieb:

    Ein Dead-Lock scheint ja zu sein, wenn sich beide Threads gegenseitig "behindern". Aber sobald eine der beiden Threads aus seiner while(1)-Schleife rausgeht, passt doch alles. Könntest du das erklären?

    In meinen anderen Bolg-Einträgen zu diesem Thema ist es an noch viel mehr Beispielen (bzw. CRT-Eigenheiten) erklärt...

    Badestrand schrieb:

    Ich selber rechne immer zu einer geringen Wahrscheinlichkeit (<0.0001%) damit, dass es sein könnte, dass irgendwelche Funktionen, und seien es welche aus der Win-API, hängenbleiben.

    Du kanst davon ausgehen: Wenn was auftreten kann, dann tritt es immer mit 100%iger Wahrscheinlichkeit bei dem Kunden auf, der eh schon Probleme hat.

    [quote="Badestrand"]Wenn ich jetzt, was dein Vorschlag ist, WaitForSingleObject( hThread, INFINITE ) benutze und eine Funktion hängenbleibt, bleibt auch mein Programm hängen (was Datenverluste zur Folge haben kann!).

    Badestrand schrieb:

    Wenn mein lieber Onkel Thread nämlich irgendwo (aus welchen Gründen auch immer!!) hängenbleiben sollte, lässt sich immerhin noch das Programm fortführen.

    Wenn Du einen Fehler in Deinem Programm hast solltest Du den Fehler suchen und nicht an den Symptomen rumdocktern...!

    Badestrand schrieb:

    Was für mich ein wichtiger Grund ist, weiterhin TerminateThread zu benutzen!

    Ich suche lieber die Ursache und behebe den Fehler als zu murksen...

    Badestrand schrieb:

    Wäre mein (sinnfreies Beispiel, siehe 2 Posts weiter oben) nicht auch ein Dead-Lock?

    Ein Dead-Lock ist das nicht, da der Thread ja auf nix wartet. Bei einem Dead-Lock warten die beiden Threads auf den jeweils anderen; was bei Deinem Beispiel nicht der Fall ist.



  • Jochen Kalmbach schrieb:

    Das hab ich ja gemeint: Es ist (für einen Laien) nicht ersichtlich wo hier der Dead-Lock sein soll. Aber wenn Du es mit MS VC++ kompilierst und es laufen lässt wirst Du nach einigen ms feststellen, dass sich das ganze aufhängt...

    Nur mal dazu: Habs mit MS VC++ 2003 kompiliert, läuft tadellos...



  • Das liegt vermutlich daran dass Dein Prozessor kein wirkliches Multi-Threading kann... (z.B. Hyperthreading). Oder Du hast es nicht mit der Multithreading-CRT übersetzt.


Anmelden zum Antworten