I learn from the following links that sub classing a QThread is not a correct way of using it...the proper way is to subclass the QObject and then move the object of QObject class to the respective thread using moveToThread() function...i followed the following links..
link 1 and link 2...but my question is then how will i be able to use msleep() and usleep() protected static functions ? or will i use QTimer to make a thread wait for some time ?
No need for timers. For waiting, Qt provides QWaitCondition. You can implement something like this:
#include <QWaitCondition>
#include <QMutex>
void threadSleep(unsigned long ms)
{
QMutex mutex;
mutex.lock();
QWaitCondition waitCond;
waitCond.wait(&mutex, ms);
mutex.unlock();
}
This is a normal function. You can of course implement it as a member function too, if you want (it can be a static member in that case.)
One solution would be to create a timer:
class Worker: public QObject
{
///...
private slots:
void doWork()
{
//...
QTimer::singleShot(delay, this, SLOT(continueDoingWork()));
}
void continueDoingWork()
{
}
};
Sometimes, you only need to run an operation in a different thread and all this event loops and threads are overhead. Then you can use QtConcurent framework:
class Worker
{
public:
void doWork()
{
//...
}
} worker;
//...
QtConcurent::run(worker, &Worker::doWork);
Then, I usually use mutexes to simulate the sleep operations:
QMutex m;
m.lock();
m.tryLock(delay);
The canonical answer is "use signals and slots."
For example, if you want a QObject in a thread to "wake itself up" after a certain period of time, consider QTimer::singleShot(), passing in the slot as the third argument. This can be called from the slot in question, resulting in periodic execution.
You can't let a different thread sleep without cooperation of this thread, thats the reason the member functions of QThread are protected. If you want to sleep a different thread you need to use a condition variable or a timer inside
If you want so sleep the current thread with usleep(), the simplest way is to subclass it - its perfectly fine as long as you don't need QThreadPool, a thread local event loop or similar.
Related
I need to share a boost::deadline_timer between two threads. The boost documentation says "The shared instances are not threadsafe". Here is an example code:
ClassA : public enable_shared_from_this<ClassA>{
ClassA()
{
m_timer = new boost::deadline_timer(m_io_service);
}
destroy()
{
m_timer->cancel();
delete m_timer;
m_timer = NULL;
}
thread_method()
{
m_timer->expire_from_now(...);
m_timer->async_wait(...);
}
run()
{
boost::thread t(ClassA::thread_method, shared_from_this);
}
}
My question is "To synchronize timer access between destroy() and thread_method(), can I use boost::atomic ?
Header:
boost::atomic<boost::deadline_timer*> m_timer;
Constructor:
m_timer = new boost::deadline_timer(m_io_service);
Is it thread-safe ?
Thank you.
No that won't help.
The atomic only makes stores/loads of the pointer indivisible. When you dereference it, you're just accessing the deadline_timer directly, unsynchronized.
So you can either
just traditional thread synchronization around all accesses to the deadline timer (e.g. using a mutex)
use an Asio strand to create a 'logical' thread of execution, and take care to only access the dead line timer from that strand.
The strand approach is potentially more efficient but requires you to think about the flow of execution more accurately so you don't accidentally create a data race
In my multi-threaded programs I often use an approach like shown below to synchronize access to data:
class MyAsyncClass
{
public: // public thread safe interface of MyAsyncClass
void start()
{
// add work to io_service
_ioServiceWork.reset(new boost::asio::io_service::work(_ioService));
// start io service
_ioServiceThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &_ioService)));
}
void stop()
{
_ioService.post(boost::bind(&MyAsyncClass::stop_internal, this));
// QUESTION:
// how do I wait for stop_internal to finish here?
// remove work
_ioServiceWork.reset();
// wait for the io_service to return from run()
if (_ioServiceThread && _ioServiceThread->joinable())
_ioServiceThread->join();
// allow subsequent calls to run()
_ioService.reset();
// delete thread
_ioServiceThread.reset();
}
void doSometing()
{
_ioService.post(boost::bind(&MyAsyncClass::doSometing_internal, this));
}
private: // internal handlers
void stop_internal()
{
_myMember = 0;
}
void doSomething_internal()
{
_myMember++;
}
private: // private variables
// io service and its thread
boost::asio::io_service _ioService;
boost::shared_ptr<boost::thread> _ioServiceThread;
// work object to prevent io service from running out of work
std::unique_ptr<boost::asio::io_service::work> _ioServiceWork;
// some member that should be modified only from _ioServiceThread
int _myMember;
};
The public interface of this class is thread-safe in the sense that its public methods can be called from any thread and boost::asio::io_service takes care that access to the private members of this class are synchronized. Therefore the public doSomething() does nothing but posting the actual work into the io_service.
The start() and stop() methods of MyAsyncClass obviously start and stop processing in MyAsyncClass. I want to be able to call MyAsyncClass::stop() from any thread and it should not return before the uninitialization of MyAsyncClass has finished.
Since in this particular case I need to modify one of my private members (that needs synchronized access) when stopping, I introduced a stop_internal() method which I post to the io_service from stop().
Now the question is: How can I wait for the execution of stop_internal() to finish inside stop()? Note that I cannot call stop_internal() directly because it would run in the wrong thread.
Edit:
It would be nice to have a solution that also works if MyAsyncClass::stop() is called from the _ioServiceThread, so that MyAsyncClass can also stop itself.
I just found a very nice solution myself:
Instead of removing work (resetting _ioServiceWork) in stop(), I do it at the end of stop_internal(). This means that _ioServiceThread->join() blocks until stop_internal() has finished - exactly what I want.
The nice thing about this solution is that it doesn't need any mutex or condition variable or stuff like this.
Is possible call method in background thread in same class? Using C++/QT without c++11.
Or repeatedly everly 5 seconds run foo2.
Example
class MyClass
{
public:
void foo(...)
{
// in another thread run foo2
foo2;
}
.
.
.
protected:
void foo2(...){}
}
thanks
to run some function in a separate thread you can use QtConcurrent::run (i use it with QFutureWatcher). To run it every 5 or so seconds, use QElapsedTimer class
QFuture<void> future = QtConcurrent::run(this, &MyClass::foo2, ...foo2 arguments);
http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run or check it here https://stackoverflow.com/search?q=QtConcurrent%3A%3Arun
or you can subclass QThread, reimplement run() with the stuff you want to happen in your thread, and then create an instance of your thread and call start() on it.
Maybe there is a really simple solution for my problem, but I'm really confused with all the boosts around me.
Here's my problem:
I want to start a task (calculation, file system operations, etc.), raised by a callback system which calls the CallbackReceived function and I want to pass this operation to a thread, typically represented by a member function of an object. The thread isn't guaranteed to finish, so it should have something to cancel it after some time.
Something like (don't know if this is 100% correct):
// ...
MyObject object;
// ...
void CallbackReceived(int parameter) {
boost::thread tThread(&MyObject::calculate, *&object);
boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::seconds(2));
tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error));
tThread.join();
}
Basically, a tThread.join()` waits for the return of the thread. While waiting, my main could not receive any callbacks that may come in because it's blocked and sleeps.
So what can one do, to run the thread and not to block the calling initial program while executing the operation?
You can call join just when you need the result of the calculations.
Something like "Future" pattern. Anyway, you would have to make your thread variable global to the CallBackRecieved function (You can write some wrapper).
Note: you can call join, when thread finished its' work - nothing will be blocked.
What do you want to do with the result of calculate?
Your main thread is blocked in the .join().
If you want to handle other callbacks, you have to return to the normal execution flow, waiting for another call.
Then you have to ask yourself what do you do with the result of calculate when it's finished. Maybe the thread can put the result in a shared resource somewhere and finish gracefully.
You must first sort out all what your code is supposed to do ( processing callbacks, starting threads, what to do with the result ) then you can think of implementing it. There are new constructs in boost and C++11 called promise and future that could suit you but first you have to think about what you want.
Actually you could call the callback while your main thread is sleeping. It would just run on the context (stack) of your thread.
You probably don't want to call join at the point you are at but later or never.
Example (pseudocode):
class Worker {
void doWork(void * mainthread){
Main* main = static_cast<Main*>(mainthread);
while(hasWorkTodo){
//work
//inform main
main->callbackwithinformation(information);
}
}
class Main{
atomi_int filesfound;
void main_part(){
//start worker
boost::thread thread(&Worker::doWork, &object, this);
while(hasworktodo){
//do work
//use filesfound here
}
//About to finish make sure we join our thread
thread.join();
}
void callbackwithinformation(int updatedcount){
//here we set a flag or pass some object
//probably will need an atomic operation
filesfound = updatedcount;
}
}
You would define the implementations in cpp and the interface in a h file so no circular dependency would arise, since you are only using Main as a argument in the interface a forward declaration would suffice.
//worker.h
class mainthread;
class Worker {
void doWork(void * mainthread);
}
//worker.cpp
#include "main.h"
void Worker::doWork(/* and so on*/}
//main.h
class Main{
atomi_int filesfound;
void main_part();
void callbackwithinformation(int updatedcount);
}
//main.cpp
//no need for worker.h here
void Main::main_part() /* implementation and so on */
I'm using a QThread and inside its run method I have a timer invoking a function that performs some heavy actions that take some time. Usually more than the interval that triggers the timer (but not always).
What I need is to protect this method so it can be invoked only if it has completed its previous job.
Here is the code:
NotificationThread::NotificationThread(QObject *parent)
: QThread(parent),
bWorking(false),
m_timerInterval(0)
{
}
NotificationThread::~NotificationThread()
{
;
}
void NotificationThread::fire()
{
if (!bWorking)
{
m_mutex.lock(); // <-- This is not protection the GetUpdateTime method from invoking over and over.
bWorking = true;
int size = groupsMarkedForUpdate.size();
if (MyApp::getInstance()->GetUpdateTime(batchVectorResult))
{
bWorking = false;
emit UpdateNotifications();
}
m_mutex.unlock();
}
}
void NotificationThread::run()
{
m_NotificationTimer = new QTimer();
connect(m_NotificationTimer,
SIGNAL(timeout()),
this,
SLOT(fire(),
Qt::DirectConnection));
int interval = val.toInt();
m_NotificationTimer->setInterval(3000);
m_NotificationTimer->start();
QThread::exec();
}
// This method is invoked from the main class
void NotificationThread::Execute(const QStringList batchReqList)
{
m_batchReqList = batchReqList;
start();
}
You could always have a thread that needs to run the method connected to an onDone signal that alerts all subscribers that it is complete. Then you should not run into the problems associated with double lock check and memory reordering. Maintain the run state in each thread.
I'm assuming you want to protect your thread from calls from another thread. Am I right? If yes, then..
This is what QMutex is for. QMutex gives you an interface to "lock" the thread until it is "unlocked", thus serializing access to the thread. You can choose to unlock the thread until it is done doing its work. But use it at your own risk. QMutex presents its own problems when used incorrectly. Refer to the documentation for more information on this.
But there are many more ways to solve your problem, like for example, #Beached suggests a simpler way to solve the problem; your instance of QThread would emit a signal if it's done. Or better yet, make a bool isDone inside your thread which would then be true if it's done, or false if it's not. If ever it's true then it's safe to call the method. But make sure you do not manipulate isDone outside the thread that owns it. I suggest you only manipulate isDone inside your QThread.
Here's the class documentation: link
LOL, I seriously misinterpreted your question. Sorry. It seems you've already done my second suggestion with bWorking.