threads abbrechen



  • Hallo Leute,

    kann man einen Thread aus dem Hauptthread heraus beenden oder geht das nur mit einer Abbruchbedingung?

    Codebeispiel:

    void timer(int interval)  // <-- wird als zusätzlicher thread ausgeführt
    {
    	while (true)
    	{
    		boost::this_thread::sleep_for(boost::chrono::seconds(interval));
    		timerEvent();
    	}
    }
    
    void timerEvent()
    {
    	//...
    }
    

    Die timer-Funktion wird in einem Thread ausgeführt und soll in einem festgelegten Intervall (meist mehrere Stunden) eine Aktion durchführen. Nun kann es aber sein, dass ich das Intervall ändern möchte. Hierfür würde ich den Thread irgendwie beenden und mit einem anderen Parameterwert neu starten. Aber wie geht das? Das einzige was mir da einfällt ist eine Abbruchbedingung in der while-Schleife. Das geht zwar, ist aber irgendwie nicht so toll.

    Bei mir läuft der Thread in einer Objektmethode. Daher sollte der Thread beim Zerstören des Objekts auch sofort beendet werden. Kann man das nicht irgendwie über die ThreadID regeln? Die könnte ich mir ja in eine Membervariable speichern. Betriebssystemspezifische APIs möchte ich dabei vermeiden.

    viele Grüße,
    SBond



  • http://www.boost.org/doc/libs/1_66_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.interruption

    ich arbeite manchmal mit dem Interruption Feature

    dann kannst du folgenden Routinen unterbrechen

    Predefined Interruption Points
    The following functions are interruption points, which will throw boost::thread_interrupted if interruption is enabled for the current thread, and interruption is requested for the current thread:

    boost::thread::join()
    boost::thread::timed_join()
    boost::thread::try_join_for(),
    boost::thread::try_join_until(),
    boost::condition_variable::wait()
    boost::condition_variable::timed_wait()
    boost::condition_variable::wait_for()
    boost::condition_variable::wait_until()
    boost::condition_variable_any::wait()
    boost::condition_variable_any::timed_wait()
    boost::condition_variable_any::wait_for()
    boost::condition_variable_any::wait_until()
    boost::thread::sleep()
    boost::this_thread::sleep_for()
    boost::this_thread::sleep_until()
    boost::this_thread::interruption_point()

    das ist besondern schön wenn dein sleep(2 Stunden) ist 🙂



  • oh *shame*

    ja das schau ich mit gleich mal an 😃
    Habe bisher noch nicht so viel mit Threads gearbeitet^^

    Danke 🙂



  • Wieso nicht einfach std::thread? Um einen Thread zu beenden musst du einfach nur dafür sorgen dass der jeweilige Thread returned... 😉



  • ok, also an eine periodische Prüfung komme ich scheinbar nicht herum. Dementsprechend werde ich mir also einen Zähler integrieren und sekündlich hochzählen. Danach prüfe ich ob eine Abbruchbedingung eingetroffen ist oder der Timeout erreicht wurde.

    Hatte anfangs gehofft dass ein Thread auch direkt beendet werden kann. naja ist jetzt nicht so wild.

    aber Danke für die Tipps 🙂



  • also es gibt funktionen, mit denen du threads direkt beenden kannst. normaler weise heißen die kill, abort, terminate oder so.



  • Ein Thread sollte immer sauber returnen.
    Ein Thread "beenden", "killen" ist schwer nachzuvollziehen, was das überhaupt bedeutet und kommt dann auch auf die unterliegende Implementierung an (pthread, Windows Threads, ...).

    Es ist einfach das sicherste und kontrollierteste.
    Außerdem muss man die Lebenszeit eines thread am Ende sowieso immer mit "join" oder "detach" kontrollieren. In fast allen Fällen würde ich behaupten ist das "join". Wo das geschieht, kann man sich auch mit einem atomic dafür sorgen, dass dieser seine Arbeit beendet.



  • SBond schrieb:

    ok, also an eine periodische Prüfung komme ich scheinbar nicht herum.

    Wie kommst du darauf? Ich dachte, du wolltest dir die Sache mit den interruption points ansehen?



  • Wade1234 schrieb:

    also es gibt funktionen, mit denen du threads direkt beenden kannst.

    Ja. Solle man bloss so gut wie nie machen. Wichtig dabei: So lange man sich fragt "wieso nicht?" bzw. sich denkt "wird schon nicht so schilmm sein" hat man das Problem nicht verstanden und sollte es daher schonmal grundsätzlich die Finger davon lassen.

    Wade1234 schrieb:

    normaler weise heißen die kill, abort, terminate oder so.

    Nö. Die Funktionen die "normalerweise kill, abort, terminate oder so heissen" beenden das ganze Programm. Das ist auch nicht toll, aber um Grössenordnungen weniger schlimm als einen Thread abzubrechen.



  • 5cript schrieb:

    Ein Thread sollte immer sauber returnen.

    Japp.

    5cript schrieb:

    Außerdem muss man die Lebenszeit eines thread am Ende sowieso immer mit "join" oder "detach" kontrollieren.

    Das wäre ja nicht das Problem. Und detach ändert an der Lebenszeit des Threads nix, sondern nur an der Lebenszeit/Gültigkeit des Thread-Handles (der Thread ID). Und die Notwendigkeit detach oder join aufzurufen wäre an und für sich kein Problem wenn es möglich wäre Threads sinnvoll/sicher abzubrechen. Dann müsste man nach das "cancel" bloss noch ein "join" dranschreiben - denn es wäre dann ja garantiert dass "join" nicht warten muss, da der Thread ja eh bereits abgebrochen wurde.

    Wobei ich detach/join für ein recht fragwürdiges Konzept halte. Also schonmal grundsätzlich weil ich es doof finde wenn es für ein und das selbe "Objekt" (in diesem Fall das Thread-Handle) mehr als einen "Destruktor" gibt (also mehr als eine Funktion mit der man das Objekt freigeben kann). Und dann doppelt wenn eine dieser Funktionen eine "warte mal bis das fertig ist" Funktion ist.



  • hustbaer schrieb:

    Wobei ich detach/join für ein recht fragwürdiges Konzept halte. Also schonmal grundsätzlich weil ich es doof finde wenn es für ein und das selbe "Objekt" (in diesem Fall das Thread-Handle) mehr als einen "Destruktor" gibt (also mehr als eine Funktion mit der man das Objekt freigeben kann). Und dann doppelt wenn eine dieser Funktionen eine "warte mal bis das fertig ist" Funktion ist.

    Hast du eine alternative Idee?

    Ich benutze prinzipiell nur join. Ich detache Threads in selten Fällen nur, wenn ich weiß, dass dieser in Micro- bis Millisekunden fertig wird.
    Besonders bei Programmende will ich feststellen, dass alles in richtiger Reihenfolge beendet wird, und sonst kein Thread mehr läuft.


Log in to reply