My question relates to using volatile for stop flag in order to stop method of some threaded server.
In some open-source projects I see declaring stop as volatile:
class ThreadedServer {
public:
//...
// this method will be launched in separate worker thread
void run() {
while (!stop_) {
//some useful work...
}
if (stop_) {
//cleanup
}
}
void stop() {
stop_ = true;
}
private:
volatile bool stop_;
};
In my server I declared a stop field WITHOUT volatile modifier, and everything works. So why to make class variable volatile in such concrete situation?
volatile signals that the value of stop_ has to be read from the main memory every time it is evaluated.
What could happen if you didn't do that, in the worst case, is to run without stopping, because thread1 sets stop_ to false, but thread2 does only look at his buffered stop on the CPU cache.
But keep in mind that it must not result in a problem, but it could.
I have a class that is exposed to QML:
qmlRegisterType("SerialThread", 1, 0, "SerialThread");
This class inherits QThread and the QThread.start() is called from QML.
When the user closes the application, how do I properly exit the thread before the program terminates?
In the destructor, you should call quit() followed by wait(). Since, hopefully, you've made QML own the thread object, it will destruct it - feel free to verify that the destructor is, in fact, executed.
If you don't spin an event loop in the thread, then you must reimplement quit() to set your own stop flag. Since you hide the underlying non-virtual quit(), your "thread" is not really a QThread anymore, and you must inherit from QThread privately - it's a semantic error to do otherwise (and leads to bad bugs).
How such bugs happen? Since you can pass your "not quite" a thread somewhere a QThread is expected, those users of it are free to assume it's a real thread, not a "not quite one", and call QThread::quit() method, which is a no-op without an event loop. Thus bugs.
To maintain LSP, if you need to override non-virtual public methods, you must privately inherit from the parent class, since it's not usable in places where its parent would be usable.
class MyThread : private QThread {
Q_OBJECT
Q_DISABLE_COPY(MyThread)
volatile bool m_stop;
void run() { ... }
public:
MyThread(QObject * parent = nullptr) : QThread(parent) { ... }
void quit() { m_stop = true; }
// It's important to fully qualify the Priority type, otherwise moc will generate
// wrong code.
Q_SLOT void start(QThread::Priority priority = InheritPriority) {
if (isRunning()) return;
m_stop = false;
QThread::start();
}
using QThread::isRunning;
using QThread::isFinished;
bool isInterruptionRequested() const { return m_stop; }
~MyThread() {
quit();
wait();
}
// Publicly we're only a QObject, not a thread
operator QObject&() { return *this; }
operator const QObject&() const { return *this; }
void run() {
while (!m_stop) { ... }
}
};
You can call thread.stop() and check thread.isRunning() before returning exit value in the main.
like you probably know boost thread requires that memeber function that is fwd as argument must be static. There is a bind way to do it if it is not static, but I prefer the Object o; o.startThread() than
Object o;
boost::thread(boost::bind....) because it keeps the thread code inside the class(also exception handling).
So for example can this be rewritten to work:
class sayHello
{
string name;
public:
sayHello(string name_):name(name_)
{
}
void repeatHello()
{
while (true)
{
boost::this_thread::sleep(posix_time::seconds(3));
cout<<"Hello "<<name<<endl;
}
}
void infiniteRun()
{
boost::thread thr(repeatHello);//broken line
}
};
P.S. for people wandering what is the "bind way" AFAIK it is this:
sayHello sh("world");
boost::thread thr(boost::bind(&sayHello::repeatHello,&sh));
Yes...
void infiniteRun()
{
boost::thread thr(boost::bind(&sayHello::repeatHello,this));
}
Although doing it that way fraught with danger of memory leaks and access violations. When dealing with threads, I would highly recommend using smart pointers to keep things alive correctly.
I am creating a thread using this call:
m_pThread=AfxBeginThread(read_data,(LPVOID)hSerial);
read_data is a static method in my class.
But I want to call a non static method and make a thread.
As I want to share a variable between this thread and one of my class method.
I tried taking a static variable but it gave some errors.
You cannot create a thread using a non-static member of a function as the thread procedure: the reason is all non-static methods of a class have an implicit first argument, this is pointer this.
This
class foo
{
void dosomething();
};
is actually
class foo
{
void dosomething(foo* this);
};
Because of that, the function signature does not match the one you need for the thread procedure. You can use a static method as thread procedure and pass the this pointer to it. Here is an example:
class foo
{
CWindThread* m_pThread;
HANDLE hSerial;
static UINT MyThreadProc(LPVOID pData);
void Start();
};
void foo::Start()
{
m_pThread=AfxBeginThread(MyThreadProc,(LPVOID)this);
}
UINT foo::MyThreadProc(LPVOID pData)
{
foo* self = (foo*)pData;
// now you can use self as it was this
ReadFile(self->hSerial, ...);
return 0;
}
I won't repeat what Marius said, but will add that I use the following:
class foo
{
CWindThread* m_pThread;
HANDLE hSerial;
static UINT _threadProc(LPVOID pData);
UINT MemberThreadProc();
void Start();
};
void foo::Start()
{
m_pThread=AfxBeginThread(_threadProc,(LPVOID)this);
}
UINT foo::MyThreadProc(LPVOID pData)
{
foo* self = (foo*)pData;
// call class instance member
return self->MemberThreadProc();
}
UINT foo::MemberThreadProc()
{
// do work
ReadFile(hSerial, ...);
return 0;
}
I follow this pattern every time I use threads in classes in MFC apps. That way I have the convenience of having all the members like I am in the class itself.
The QFuture class has methods such as cancel(), progressValue(), etc. These can apparently be monitored via a QFutureWatcher. However, the documentation for QtConcurrent::run() reads:
Note that the QFuture returned by
QtConcurrent::run() does not support
canceling, pausing, or progress
reporting. The QFuture returned can
only be used to query for the
running/finished status and the return
value of the function.
I have looked in vain for what method actually can create a QFuture that can be cancelled and report progress for a single long-running operation. (It looks like maybe QtConcurrent::map() and similar functions can, but I just have a single, long-running method.)
(For those familiar with .Net, something like the BackgroundWorker class.)
What options are available?
Though it's been a while since this question was posted and answered I decided to add my way of solving this problem because it is rather different from what was discussed here and I think may be useful to someone else. First, motivation of my approach is that I usually don't like to invent own APIs when framework already has some mature analogs. So the problem is: we have a nice API for controlling background computations represented by the QFuture<>, but we have no object that supports some of the operations. Well, let's do it. Looking on what's going on inside QtConcurrent::run makes things much clearer: a functor is made, wrapped into QRunnable and run in the global ThreadPool.
So I created generic interface for my "controllable tasks":
class TaskControl
{
public:
TaskControl(QFutureInterfaceBase *f) : fu(f) { }
bool shouldRun() const { return !fu->isCanceled(); }
private:
QFutureInterfaceBase *fu;
};
template <class T>
class ControllableTask
{
public:
virtual ~ControllableTask() {}
virtual T run(TaskControl& control) = 0;
};
Then, following what is made in qtconcurrentrunbase.h I made q-runnable for running this kind of tasks (this code is mostly from qtconcurrentrunbase.h, but slightly modified):
template <typename T>
class RunControllableTask : public QFutureInterface<T> , public QRunnable
{
public:
RunControllableTask(ControllableTask<T>* tsk) : task(tsk) { }
virtial ~RunControllableTask() { delete task; }
QFuture<T> start()
{
this->setRunnable(this);
this->reportStarted();
QFuture<T> future = this->future();
QThreadPool::globalInstance()->start(this, /*m_priority*/ 0);
return future;
}
void run()
{
if (this->isCanceled()) {
this->reportFinished();
return;
}
TaskControl control(this);
result = this->task->run(control);
if (!this->isCanceled()) {
this->reportResult(result);
}
this->reportFinished();
}
T result;
ControllableTask<T> *task;
};
And finally the missing runner class that will return us controllable QFututre<>s:
class TaskExecutor {
public:
template <class T>
static QFuture<T> run(ControllableTask<T>* task) {
return (new RunControllableTask<T>(task))->start();
}
};
The user should sublass ControllableTask, implement background routine which checks sometimes method shouldRun() of TaskControl instance passed to run(TaskControl&) and then use it like:
QFututre<int> futureValue = TaskExecutor::run(new SomeControllableTask(inputForThatTask));
Then she may cancel it by calling futureValue.cancel(), bearing in mind that cancellation is graceful and not immediate.
I tackled this precise problem a while ago, and made something called "Thinker-Qt"...it provides something called a QPresent and a QPresentWatcher:
http://hostilefork.com/thinker-qt/
It's still fairly alpha and I've been meaning to go back and tinker with it (and will need to do so soon). There's a slide deck and such on my site. I also documented how one would change Mandelbrot to use it.
It's open source and LGPL if you'd like to take a look and/or contribute. :)
Yan's statement is inaccurate. Using moveToThread is one way of achieving the proper behavior, but it not the only method.
The alternative is to override the run method and create your objects that are to be owned by the thread there. Next you call exec(). The QThread can have signals, but make sure the connections are all Queued. Also all calls into the Thread object should be through slots that are also connected over a Queued connection. Alternatively function calls (which will run in the callers thread of execution) can trigger signals to objects that are owned by the thread (created in the run method), again the connections need to be Queued.
One thing to note here, is that the constructor and destructor are running in the main thread of execution. Construction and cleanup need to be performed in run. Here is an example of what your run method should look like:
void MythreadDerrivedClass::run()
{
constructObjectsOnThread();
exec();
destructObjectsOnThread();
m_waitForStopped.wakeAll();
}
Here the constructObjectsOnThread will contain the code one would feel belongs in the constructor. The objects will be deallocated in destructObjectsOnThread. The actual class constructor will call the exit() method, causing the exec() to exit. Typically you will use a wait condition to sit in the destructor till the run has returned.
MythreadDerivedClass::~MythreadDerivedClass()
{
QMutexLocker locker(&m_stopMutex);
exit();
m_waitForStopped.wait(locker.mutex(), 1000);
}
So again, the constructor and destructor are running in the parent thread. The objects owned by the thread must be created in the run() method and destroyed before exiting run. The class destructor should only tell the thread to exit and use a QWaitCondition to wait for the thread to actually finish execution. Note when done this way the QThread derived class does have the Q_OBJECT macro in the header, and does contain signals and slots.
Another option, if you are open to leveraging a KDE library, is KDE's Thread Weaver. It's a more complete task based multitasking implementation similar QtConcurrentRun in that it leverages a thread pool. It should be familiar for anyone from a Qt background.
That said, if you are open to a c++11 method of doing the same thing, I would look at std::async. For one thing, you will no longer have any dependance on Qt, but the api also makes more clear what is going on. With MythreadDerivedClass class inheriting from QThread, the reader gets the impression that MythreadDerivedClass is a thread (since it has an inheritance relationship), and that all its functions run on a thread. However, only the run() method actually runs on a thread. std::async is easier to use correctly, and has fewer gotcha's. All our code is eventually maintained by someone else, and these sorta things matter in the long run.
C++11 /w QT Example:
class MyThreadManager {
Q_OBJECT
public:
void sndProgress(int percent)
void startThread();
void stopThread();
void cancel() { m_cancelled = true; }
private:
void workToDo();
std::atomic<bool> m_cancelled;
future<void> m_threadFuture;
};
MyThreadedManger::startThread() {
m_cancelled = false;
std::async(std::launch::async, std::bind(&MyThreadedManger::workToDo, this));
}
MyThreadedManger::stopThread() {
m_cancelled = true;
m_threadfuture.wait_for(std::chrono::seconds(3))); // Wait for 3s
}
MyThreadedManger::workToDo() {
while(!m_cancelled) {
... // doWork
QMetaInvoke::invokeMethod(this, SIGNAL(sndProgress(int)),
Qt::QueuedConnection, percentDone); // send progress
}
}
Basically, what I've got here isn't that different from how your code would look like with QThread, however, it is more clear that only workToDo() is running on the thread and that MyThreadManager is only managing the thread and not the thread itself. I'm also using MetaInvoke to send a queued signal for sending our progress updates with takes care of the progress reporting requirement. Using MetaInvoke is more explicit and always does the right thing (doesn't matter how you connect signals from your thread managers to other class's slots). You can see that the loop in my thread checks an atomic variable to see when the process is cancelled, so that handles the cancellation requirement.
Improve #Hatter answer to support Functor.
#include <QFutureInterfaceBase>
#include <QtConcurrent>
class CancellationToken
{
public:
CancellationToken(QFutureInterfaceBase* f = NULL) : m_f(f){ }
bool isCancellationRequested() const { return m_f != NULL && m_f->isCanceled(); }
private:
QFutureInterfaceBase* m_f;
};
/*== functor task ==*/
template <typename T, typename Functor>
class RunCancelableFunctorTask : public QtConcurrent::RunFunctionTask<T>
{
public:
RunCancelableFunctorTask(Functor func) : m_func(func) { }
void runFunctor() override
{
CancellationToken token(this);
this->result = m_func(token);
}
private:
Functor m_func;
};
template <typename Functor>
class RunCancelableFunctorTask<void, Functor> : public QtConcurrent::RunFunctionTask<void>
{
public:
RunCancelableFunctorTask(Functor func) : m_func(func) { }
void runFunctor() override
{
CancellationToken token(this);
m_func(token);
}
private:
Functor m_func;
};
template <class T>
class HasResultType
{
typedef char Yes;
typedef void *No;
template<typename U> static Yes test(int, const typename U::result_type * = 0);
template<typename U> static No test(double);
public:
enum { Value = (sizeof(test<T>(0)) == sizeof(Yes)) };
};
class CancelableTaskExecutor
{
public:
//function<T or void (const CancellationToken& token)>
template <typename Functor>
static auto run(Functor functor)
-> typename std::enable_if<!HasResultType<Functor>::Value,
QFuture<decltype(functor(std::declval<const CancellationToken&>()))>>::type
{
typedef decltype(functor(std::declval<const CancellationToken&>())) result_type;
return (new RunCancelableFunctorTask<result_type, Functor>(functor))->start();
}
};
User example:
#include <QDateTime>
#include <QDebug>
#include <QTimer>
#include <QFuture>
void testDemoTask()
{
QFuture<void> future = CancelableTaskExecutor::run([](const CancellationToken& token){
//long time task..
while(!token.isCancellationRequested())
{
qDebug() << QDateTime::currentDateTime();
QThread::msleep(100);
}
qDebug() << "cancel demo task!";
});
QTimer::singleShot(500, [=]() mutable { future.cancel(); });
}
For a long running single task, QThread is probably your best bet. It doesn't have build-in progress reporting or canceling features so you will have to roll your own. But for simple progress update it's not that hard. To cancel the task, check for a flag that can be set from calling thread in your task's loop.
One thing to note is if you override QThread::run() and put your task there, you can't emit signal from there since the QThread object is not created within the thread it runs in and you can't pull the QObject from the running thread. There is a good writeup on this issue.