QThread的工人

时间:2015-02-12 17:38:41

标签: multithreading qt qthread

我在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,程序正常运行而不会崩溃。这样安全吗?

1 个答案:

答案 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函数,则永远不会发生。