【问题标题】:How can I protect a QThread function so it will not be called again until finished its previous work?如何保护 QThread 函数,使其在完成之前的工作之前不会再次被调用?
【发布时间】:2011-08-03 14:48:06
【问题描述】:

我正在使用 QThread,在它的 run 方法中,我有一个计时器调用一个函数,该函数执行一些需要一些时间的繁重操作。通常超过触发计时器的时间间隔(但并非总是如此)。

我需要保护这个方法,只有在它完成之前的工作后才能调用它。

代码如下:

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();
}

【问题讨论】:

标签: c++ qt qthread


【解决方案1】:

您可能总是有一个线程需要运行连接到一个 onDone 信号的方法,该信号会提醒所有订阅者它已完成。那么你不应该遇到与双重锁检查和内存重新排序相关的问题。在每个线程中保持运行状态。

【讨论】:

    【解决方案2】:

    我假设您想保护您的线程免受来自另一个线程的调用。我对吗?如果是,那么..

    这就是 QMutex 的用途。 QMutex 为您提供了一个接口来“锁定”线程,直到它“解锁”,从而序列化对线程的访问。您可以选择解锁线程,直到它完成工作。但使用它需要您自担风险。如果使用不当,QMutex 会出现其自身的问题。有关这方面的更多信息,请参阅文档。

    但是还有很多方法可以解决您的问题,例如,@Beached 提出了一种更简单的方法来解决问题;如果完成,您的 QThread 实例将发出一个信号。或者更好的是,在你的线程中创建一个bool isDone,如果它完成了,那么它将是true,或者如果它没有,则为false。如果它是true,那么调用该方法是安全的。但请确保不要在拥有它的线程之外操纵isDone。我建议你只在 QThread 中操作 isDone

    这是课程文档:link

    大声笑,我严重误解了你的问题。对不起。看来你已经用bWorking 完成了我的第二个建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-04
      • 1970-01-01
      • 2018-11-24
      • 2011-04-07
      • 2019-01-10
      • 1970-01-01
      相关资源
      最近更新 更多