2012-11-16 450 views
4

我在Qt中構建了自己的阻塞隊列,並且遇到了一些問題。如果我不關閉隊列,那麼在控制檯「QWaitCondition: Destroyed while threads are still waiting」中出現錯誤。另一方面,在關閉隊列後(無論是在構造函數中還是從另一個線程中),我都會遇到訪問衝突異常。等待條件的等待方法發生異常。BlockingQueue的QWaitCondition:在線程仍在等待時銷燬

這裏是我的阻塞隊列:

#ifndef BLOCKING_QUEUE_H 
#define BLOCKING_QUEUE_H 

#include <QObject> 
#include <QSharedPointer> 
#include <QWaitCondition> 
#include <QMutex> 
#include <queue> 

namespace Concurrency 
{ 
    template<typename Data> 
    class BlockingQueue 
    { 
    private: 
     QMutex _mutex; 
     QWaitCondition _monitor; 
     volatile bool _closed; 
     std::queue<QSharedPointer<Data>> _queue; 

    public: 
     BlockingQueue() 
     { 
      _closed = false; 
     } 

     ~BlockingQueue() 
     { 
      Close(); // When this is enabled, I get an access violation exception in TryDequeue 
     } 

     void Close() 
     { 
      QMutexLocker locker(&_mutex); 
      if(!_closed) 
      { 
       _closed = true; 
       _queue.empty(); 
       _monitor.wakeAll(); 
      } 
     } 

     bool Enqueue(QSharedPointer<Data> data) 
     { 
      QMutexLocker locker(&_mutex); 

      // Make sure that the queue is not closed 
      if(_closed) 
      { 
       return false; 
      } 

      _queue.push(data); 

      // Signal all the waiting threads 
      if(_queue.size()==1) 
      { 
       _monitor.wakeAll(); 
      } 

      return true; 
     } 

     bool TryDequeue(QSharedPointer<Data>& value, unsigned long time = ULONG_MAX) 
     { 
      QMutexLocker locker(&_mutex); 

      // Block until something goes into the queue 
      // or until the queue is closed 
      while(_queue.empty()) 
      { 
       if(_closed || !_monitor.wait(&_mutex, time)) // <-- Access violation if I call close in the destructor 
       { 
        return false; 
       } 
      } 

      // Dequeue the next item from the queue 
      value = _queue.front(); 
      _queue.pop(); 
      return true; 
     } 
    }; 
} 
#endif BLOCKING_QUEUE_H 

我假設這種情況的發生,因爲隊列已被破壞後的等待線程獲取信號和互斥隨後被破壞了。當線程在TryDequeue中被喚醒時,互斥鎖不再被分配,因此它會導致訪問衝突異常。避免這種情況的最好方法是什麼?

回答

0

我遇到了相關的穿線方法的問題,更多信息一起來看看這個問題:Why is QThread::finished signal not being emitted?

使用BlockingQueue沒有正確地關閉那個等待隊列中的線程是服務並且隨後線程在TryDequeue方法內仍在等待時導致隊列被銷燬。