2014-10-22 4 views
0

Существует 2-резьбовое приложение; Поток GUI добавляет задачи, рабочий поток обрабатывает их. Однако иногда Q_ASSERT обнаруживает ложную задачу.QThread занимает некоторое время, чтобы проснуться?

Итак, вопрос: возможно ли, что

  1. Thread 1 запирает мьютекс, устанавливает _hasTask истина, вызывает wakeAll, и разблокирует мьютекс,
  2. _hasTaskCondition запомнит, что он должен проснуться, но не имеет времени для блокировки мьютекса, потому что
  3. Тема 1 снова вызывает addTask с ложным аргументом, блокирует мьютекс, устанавливает _hasTask в false, не вызывает wakeAll сейчас, разблокирует мьютекс.
  4. Итак, теперь Thread 2 имеет _hasTask == false, но поток проснулся, блокирует мьютекс и обрабатывает задачу => стрела.

Некоторые отладки (MSVC 2013) показывают, что это может произойти. Если Qt не допускает такой сценарий, то что, вероятно, происходит здесь?


упрощенный код, чтобы проиллюстрировать логику:

Class работник, переменные члены:

unsigned int _taskData; // init with 0 
QMutex   _mutex; 
QWaitCondition _hasTaskCondition; 

резьбы 1 (GUI QThread):

резьбы 2 (рабочий QThread):

// In a loop state 

void Worker::doWork() 
{ 
    unsigned int currentTaskData = 0; 
    while (true) 
    { 
     _mutex.lock(); 
     if (_taskData == 0) 
      _hasTaskCondition.wait(&_mutex); 

     Q_ASSERT(_taskData > 0); // error at some moment 

     // copy task to process it without locking the mutex 
     currentTaskData = _taskData; 
     _taskData = 0; 

     _mutex.unlock(); 

     // Process currentTaskData: 
     // some useful work without touching 
     // _hasTask, _mutex and _hasTaskCondition variables 
    } 
} 

ответ

0

Изменение, если какое-то время:

while(_taskData == 0) 
    _hasTaskCondition.wait(&_mutex); 

Тогда, когда wakeAll происходит поток будет перепроверить, если он на самом деле имеет задачу, а затем продолжить ожидание

+0

Как здесь, с Pthreads: HTTP: // StackOverflow .com/questions/4544234/call-pthread-cond-signal-without-locking-mutex –

+0

Но в примере Qt такой цикл отсутствует: http://qt-project.org/doc/qt-4.8/qwaitcondition.html –

+0

Это как раз идиома для переменных ожидания, вы блокируете и начинаете проверять проверку вашей переменной в цикле и ждать состояния в теле цикла. –

Смежные вопросы