我在QThread中有一个worker对象在无限循环中运行一些东西。 在某个地方,我看到了一个代码,在工作者那里有例如' checkStatus()'返回一些布尔值的方法。此方法不是插槽,而是公共方法。我感兴趣的是,如果这个worker对象已经被移动到QThread并且正在运行它的无限循环,那么从主线程调用这个方法是否安全?我不应该使用信号槽吗?
我在主窗口的构造函数中尝试过类似的东西:
....
startDataInputSlot(); // starting thread and moving worker into thread
while(1) dataInputWorker->checkStoppedStatus(); // trying to access some variables in worker object
....
startDataInputSlot()启动了一个线程并将worker移动到该线程中。在无限循环的worker中,它会定期检查下一个无限循环(在主窗口中)尝试访问的值。没有使用QMutex,程序正常运行而不会崩溃。这样安全吗?
答案 0 :(得分:3)
在没有互斥锁的情况下直接访问工作人员是不安全的。 这是如何实现它的一个例子:
class Worker : public QObject
{
public slots:
void doHeavyJob()
public:
bool getStatus();
private:
int data;
QMutex mutex;
}
doHeavyJob
是修改data
变量的主要工作函数。它应该通过信号槽机制启动,因为在这种情况下它将在工作线程中运行:
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();
在这里,您可以直接从另一个(主要)线程检查工作人员状态:
bool Worker::getStatus()
{
bool isGood;
mutex.lock();
isGood = data > 10;
mutex.unlock();
return isGood;
}
在getStatus
内,你应该锁定data
变量,因为它可以在工作线程中运行的doHeavyJob
槽内更改。
此外,您无法将getStatus
函数作为插槽启动,因为它仅在控件返回到工作线程事件循环时执行,但如果您具有'无限'doHeavyJob
函数,则永远不会发生。