【问题标题】:Thread-safe queue with pthreads带 pthread 的线程安全队列
【发布时间】:2015-09-17 15:27:28
【问题描述】:

这是在 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);
}

【问题讨论】:

  • 更好地使用 std::mutex aso 的 c++ 标准功能。
  • 这个问题可能也适合Code Review,尤其是在您对代码的各个方面进行了更详细的讨论时。
  • 不,这并不完全正确。一旦在您的 cvar 上发出信号,您就永远不会重新检查 Dequeue 中的空谓词。你假设因为你收到了一个唤醒它必须是非空的,这是不能保证的,尤其是spurious wakeups

标签: c++ multithreading pthreads


【解决方案1】:

您的Dequeue 需要在pthread_cond_wait() 上循环:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多