2015-06-30 174 views
1

这是在C++中实现线程安全队列的正确方法吗?我有多个线程不断排队和离队项目,直到发生某种情况,在此期间我“停止”队列。 感谢带线程的线程安全队列

#include <queue> 
#include <pthread.h> 

template <typename T> 
class ThreadSafeQueue { 

private: 
    std::queue<T> _queue; 
    pthread_mutex_t queueMutex; 
    pthread_cond_t emptyCondVar; 

public: 
    ThreadSafeQueue(); 

    bool volatile Stopped; 

    void Enqueue(T data); 
    T Dequeue(); 
    void StopQueue(); 
    void DestroyQueue(); 
}; 

template <typename T> 
ThreadSafeQueue<T>::ThreadSafeQueue() { 
    pthread_mutex_init(&queueMutex, NULL); 
    pthread_cond_init(&emptyCondVar, NULL); 
    Stopped = false; 
} 

template <typename T> 
void ThreadSafeQueue<T>::Enqueue(T data) { 
    pthread_mutex_lock(&queueMutex); 
    _queue.push(data); 
    pthread_cond_signal(&emptyCondVar); 
    pthread_mutex_unlock(&queueMutex); 

} 

template <typename T> 
T ThreadSafeQueue<T>::Dequeue() { 

    pthread_mutex_lock(&queueMutex); 
    if (_queue.empty()) { 
     pthread_cond_wait(&emptyCondVar, &queueMutex); 
    } 
    if (Stopped) { 
     pthread_mutex_unlock(&queueMutex); 
     return NULL; 
    } 

    T elem = _queue.front(); 
    _queue.pop(); 
    pthread_mutex_unlock(&queueMutex); 
    return elem; 
} 

template <typename T> 
void ThreadSafeQueue<T>::StopQueue() { 
    pthread_mutex_lock(&queueMutex); 
    Stopped = true; 
    pthread_cond_broadcast(&emptyCondVar); 
    pthread_mutex_unlock(&queueMutex); 
} 

template <typename T> 
void ThreadSafeQueue<T>::DestroyQueue() { 
    pthread_mutex_lock(&queueMutex); 
    _queue = std::queue<T>(); 
    pthread_mutex_unlock(&queueMutex); 
} 
+4

更好的使用['标准:: mutex'] C++标准功能(http://en.cppreference.com/ w/cpp/thread/mutex)aso。 –

+3

这个问题可能也适用于[代码评论](https://codereview.stackexchange.com/),尤其是如果您在对代码的各个方面进行更详细的讨论之后。 – 5gon12eder

+2

不,不论是否完全正确。一旦在你的cvar上发信号,你就再也不会检查'Dequeue'中的空谓词。你假设,因为你收到唤醒它必须是非空的,这是不能保证,特别是[虚假唤醒](http://stackoverflow.com/questions/8594591/why-does-pthread-cond-wait-have-杂散唤醒) – WhozCraig

回答

1

Dequeue需要在循环中pthread_cond_wait()

while (_queue.empty() && !Stopped) { 
    pthread_cond_wait(&emptyCondVar, &queueMutex); 
}