c++ - How to properly interrupt a QThread infinite loop -
i'm done implementing go program human can interrupt @ time software order play. basically, i've got algorithm running in thread has @ every moment "best move" available, keeps on improving.
my question : how correctly interrupt thread in infinite loop?
i've tried few things, , resolved :
class myworker : public qobject { q_object public: myworker(); ~myworker(); public: threadcontrol * getthreadcontrol(); public slots: void work(); private: void endofcomputation(); private: threadcontrol * threadcontrol; }
notice don't subclass qthread:
class threadcontrol : public qobject { q_object public: threadcontrol(); public: bool getabort(); parameter getparameter(); void setparameter(parameter & param); public slots: void setabort(bool b); private: qmutex mutex; bool abort; parameter param; };
and, finally, infinite loop coded :
void myworker::work() { // ... forever { abort = threadcontrol->getabort(); if(abort) { break; } // ... } endofcomputation(); }
then, can guess, in main
, regularly call threadcontrol::setabort(true)
basically, keep pointer boolean in main thread , toggle when want to. (the boolean encapsulated in threadcontrol
can lock mutex). far good, has worked me... seems disgusting me! toggling pointers booleans sound ... bad programming me...
the problem documentation on web (entirely?) producers , consumers threads, finish after finite time, not when asked to. interrupting thread not developped, that's why i'm asking : is there better way?
that sounds way it. give @ how has been made boost thread. because uses exceptions abort thread, permits interrupt thread in several places using interruption_point
. using thread model write thread function this:
void myfunction(){ boost::this_thread::interruption_point(); } void myworker::work() { // ... try { forever { boost::this_thread::interruption_point(); // work boost::this_thread::interruption_point(); // work again myfunction(); // interruption might triggered inside function } endofcomputation(); } catch(boost::thread_interrupted const &){ // thread has been interrupted } }
i think internally, use boolean (per thread) set true when boost::thread::interrupt()
method called.
edit
my goal show how boost resolved problem. of course, not work qthread. don't want switch boost::thread either.
edit2 quick implementation qthread:
void function(); class myworker : public qthread { public: myworker() : m_isinterrupted(false) {} class interruptionexception { public: interruptionexception(){} }; static void interruptionpoint(){ myworker * myworker = dynamic_cast<myworker*>(qthread::currentthread()); if(myworker){ if(myworker->m_isinterrupted){ throw interruptionexception(); } } } public slots: void interrupt(){ m_isinterrupted = true; } void work(){ try { while(true){ myworker::interruptionpoint(); function(); } } catch(interruptionexception const &){ } } private: bool m_isinterrupted; }; void function(){ myworker::interruptionpoint(); }
Comments
Post a Comment