I have a worker object in a QThread running some stuff in infinite loop. Somewhere I saw a code that in the worker there was for example 'checkStatus()' method returning some boolean value. This method is not slot but a public method. What I am interested in, wether is it safe to call this method from the main thread if this worker object is already moved into a QThread and is running its infinite loop? Shouldn't I use signals-slots instead?
I tried something like this in constructor of main window:
....
startDataInputSlot(); // starting thread and moving worker into thread
while(1) dataInputWorker->checkStoppedStatus(); // trying to access some variables in worker object
....
startDataInputSlot() started a thread and moved the worker into that thread. In infinite loop of worker it periodically checks the value which the next infinite cycle (in main window) tries to access. No QMutexes were used and a program worked properly without crashing. Is this safe to use?
It is not safe to have a direct access to worker members without mutexes. This is an example of how it can be implemented:
class Worker : public QObject
{
public slots:
void doHeavyJob()
public:
bool getStatus();
private:
int data;
QMutex mutex;
}
doHeavyJob
is the main worker function which modifies the data
variable. It should be launched via signal-slot mechanism, as in this case it will be running in the the worker thread:
void Worker::doHeavyJob()
{
while (true)
{
mutex.lock();
// do something with the data
data++;
mutex.unlock();
}
}
QThread *thread = new QThread;
Worker *worker = new Worker;
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(doHeavyJob()));
thread->start();
And here you can check the worker status directly from another (main) thread:
bool Worker::getStatus()
{
bool isGood;
mutex.lock();
isGood = data > 10;
mutex.unlock();
return isGood;
}
Inside getStatus
you should lock the data
variable because it can be changed inside doHeavyJob
slot which is running in the worker thread.
Also you can't launch getStatus
function as a slot because it will be only executed when the control returns to the worker thread event loop, but if you have 'infinite' doHeavyJob
function, it will never happen.