Boost Threads in Klassen. Gefährlich?
-
Ich würde Threads nicht einfach terminieren.
Probiere Sie auslaufen zu lassen.
z.B. klassenglobale, threadsichere, boolsche Variable "a"
void thread(){ while(a){ //whatever... } }
irgendwo außerhalb des Threads setzt du die Variable a auf "false" und der Thread beendet sich.
Wenn du erst nach Beendigung des Threads in der main weiter arbeiten möchtest, könntest du das wieder mit .join(); realisieren.
-
Kann man die Threads eigentlich irgendwie sehen? Mit htop sehe ich ja Prozesse, aber keine Threads. Es wäre vielleicht ganz nützlich zu sehen wenn einer wirklich beendet wird.
-
Also in Visual Studio kann man sehen, was mit Threads passiert. Auch wenn sie beendet werden. Weiss nicht, wie das in anderen IDE's so ist.
-
Ich verwende einfach einen Editor und g++ unter Linux, also keine IDE. Sonst kann man das nicht irgendwie sehen?
WAR][FIRE: so hab ich das nun auch gemacht! Jedes Modul hat eine bool laufen und eine Methode stoppen() welche diese auf false setzt.
Das Problem ist nun nur, was ist wenn ein Thread gerade wait() aufgerufen hat und auf etwas wartet? Und zwar auf etwas was wegen dem stoppen() gar nicht mehr eintritt?
-
Da gibt es wieder funtktionen, die nach einer bestimmten wartezeit aufhören zu warten. Wenn nach einer bestimmten Zeit nichts gekommen ist, dann wird halt abgebrochen und entsprechens reagiert.
Weiter könntest du dir eine Art Messagebaox Prinzip ausdenken. Sprich eine Variable setzen, in der geschrieben wird, dass ein Thread sich nun abmeldet.
Sprich:
void thread(){ while(a){ //whatever.. } //Hier wird in eine Variable geschrieben, dass der Thread nun dicht ist. }
Diese Variable musst du in dem Thread, der auf ein ereignis wartet natürlich abfragen.
Das ist das was mir so jetzt einfällt. Für eine konkrete Antwort weiß ich zu wenig über das was du realisieren möchtest.
Gruß
WAR][FIRE
-
fabske schrieb:
Ich verwende einfach einen Editor und g++ unter Linux, also keine IDE. Sonst kann man das nicht irgendwie sehen?
Auf die Hardcore-Art geht es natürlich auch. Du musst dazu aber dein Programm mit Debugging-Symbols kompilieren, dass machst du mit der Option
-g
.
Danach kannst du dengdb
anschmeissen und während das Programm läuft mit zum Beispielinfo threads
die aktuell laufenden Threads anschauen.Infos zum GDB:
http://www.gnu.org/software/gdb/Dokumentation GDB:
http://sourceware.org/gdb/current/onlinedocs/gdb/Dokumentation GDB & Multithreading:
http://sourceware.org/gdb/current/onlinedocs/gdb/Threads.html#ThreadsGrüssli
-
ich versuchs!
-
Ich will in diesem Thread mal wieder was zur ursprünglichen Frage posten. Bisher habe ich in all meinen Modulen im Konstruktor folgende Variante um das Modul als Thread zu starten:
BeispielModul::BeispielModul() { boost::thread Faden = boost::thread(boost::bind(&BeispielModul::arbeiten, this)); };
Jedes Modul ist von Modul abgeleitet und implementiert die virtuelle Funktion arbeiten().
Nun möchte ich Module auch wieder stoppen können und verlagere das Starten des Threads in eine neue Funktion Modul::starteModul. Am besten wäre, wenn ich das gleich für jedes Modul gemeinsam schreiben könnte, da ja jedes diese Funktion erben wird.void Modul::starteModul(void) { Faden = boost::thread(boost::bind(arbeiten, this)); };
Wie gesagt, die arbeiten ist im Modul.hpp als virtual void arbeiten() = 0; deklariert und wird von den erbenden Modulen implementiert. Leiderklappt das nicht und ich würde gerne wissen warum. Was macht denn das "this"?
Vielen Dank!
-
Ich mache das immer so aehnlich, wenn eine Methode in einem eigenen Thread ausgefuehrt werden soll (ganz ohne boost, aber leicht auf boost uebertragbar): http://www.linuxselfhelp.com/HOWTO/C++Programming-HOWTO-18.html
-
Die Reihenfolge, in der Objekte konstruiert werden, ist Basisklasse -> abgeleitete Klasse. Dein Basisklassenkonstruktor versucht also, eine virtuelle Funktion für etwas aufzurufen, das zu dem Zeitpunkt noch gar nicht existiert. (Link dazu)
Das Schöne an boost::thread ist ja gerade, dass man nicht irgendwelche abstrakten Thread-Basisklassen benötigt, sondern ganz einfach jede Funktion einer Klasse (oder auch freie) in einem eigenen Thread laufen lassen kann. Also ab besten einfach den Thread da anlegen, wo er gebraucht wird (in der abgeleiteten Klasse).
-
Btw: Wie bei fast jeder Klasse, würde ich als Klassenmember für boost::thread einen boost::scoped_ptr nehmen.
-
Kóyaánasqatsi schrieb:
Btw: Wie bei fast jeder Klasse, würde ich als Klassenmember für boost::thread einen boost::scoped_ptr nehmen.
Warum? boost::thread ist movable...
Simon