I’m done implementing a Go program where the human can interrupt at any time the software to order it to play. Basically, I’ve got an algorithm running in another thread that has at every moment a “Best move” available, that it keeps on improving.
My question is : how do I correctly interrupt a thread in an infinite loop?
I’ve tried a few things, and resolved to do this :
class MyWorker : public QObject
{
Q_OBJECT
public:
MyWorker();
~MyWorker();
public:
ThreadControl * getThreadControl();
public slots:
void work();
private:
void endOfComputation();
private:
ThreadControl * threadControl;
}
Notice that I 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, the infinite loop is coded as this :
void Myworker::work()
{
// ...
forever
{
abort = threadControl->getAbort();
if(abort)
{
break;
}
// ...
}
endOfComputation();
}
Then, as you can guess, in the main, I regularly call ThreadControl::setAbort(true)
Basically, I just keep a pointer to a boolean in the main thread and I toggle it when I want to. (The boolean is encapsulated in ThreadControl so I can properly lock it with a mutex). So far so good, it has worked for me… But it seems disgusting to me! Toggling pointers to booleans sound like … bad programming to me…
The problem is the documentation on the web is mostly (entirely?) about producers and consumers threads, which finish after a finite time, not when asked to. Interrupting a thread is not developped, that’s why I’m asking : Is there a better way?
That sounds a good way to do it. You could also give a look at how it has been made it boost thread. Because it uses exceptions to abort the thread, it permits you to interrupt the thread in several places using
interruption_point. Using their thread model you could write your thread function like this:I think that internally, they use a boolean (per thread) which is set to true when
boost::thread::interrupt()method is called.EDIT
My goal is to show you how boost resolved this problem. Of course, this will not work with your QThread. I don’t want you to switch to boost::thread either.
EDIT2 Quick implementation with QThread: