Как я могу защитить функцию QThread, чтобы она не вызывалась снова, пока она не закончит свою предыдущую работу? - PullRequest
2 голосов
/ 03 августа 2011

Я использую 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();
}

Ответы [ 2 ]

0 голосов
/ 18 декабря 2011

Я предполагаю, что вы хотите защитить свой поток от вызовов из другого потока.Я прав?Если да, то ..

Это то, для чего предназначен QMutex.QMutex предоставляет вам интерфейс для «блокировки» потока, пока он не будет «разблокирован», тем самым сериализовав доступ к потоку.Вы можете разблокировать поток, пока он не выполнит свою работу.Но используйте его на свой страх и риск.QMutex представляет свои проблемы при неправильном использовании.Обратитесь к документации для получения дополнительной информации по этому вопросу.

Но есть много других способов решения вашей проблемы, например, @Beached предлагает более простой способ решения проблемы;ваш экземпляр QThread издаст сигнал, если это будет сделано.Или, что еще лучше, создайте bool isDone внутри вашей темы, которая будет true, если это будет сделано, или false, если это не так.Если когда-либо это true, тогда безопасно вызывать метод.Но убедитесь, что вы не манипулируете isDone вне потока, которому он принадлежит.Я предлагаю вам манипулировать только isDone внутри вашего QThread.

Вот документация класса: ссылка

LOL, я серьезно неверно истолковал ваш вопрос.Сожалею.Похоже, вы уже сделали мое второе предложение с bWorking.

0 голосов
/ 17 августа 2011

У вас всегда может быть поток, которому нужно запустить метод, связанный с сигналом onDone, который предупреждает всех подписчиков, что он завершен.Тогда вам не следует сталкиваться с проблемами, связанными с проверкой двойной блокировки и переупорядочением памяти.Поддерживать состояние выполнения в каждом потоке.

...