21xrx.com
2024-11-05 18:49:51 Tuesday
登录
文章检索 我的文章 写文章
C++生产消费队列实现
2023-06-22 08:29:19 深夜i     --     --
C++ 生产消费 队列 实现

生产消费队列是一种重要的数据结构,它常用于多线程编程中,其中生产者线程向队列中生产数据,而消费者线程从队列中消费数据。在多线程环境下,生产消费队列的实现需要考虑线程竞争问题,以保证数据的正确性和可靠性。本文将介绍C++语言中的生产消费队列实现方法。

C++语言中提供了std::queue 类模板作为队列的基础实现。它提供了push()和pop()等接口,用于生产和消费队列中的数据。但是,std::queue 并不是线程安全的。如果在多线程环境下使用它,可能会导致数据竞争和线程安全问题。因此,我们需要对std::queue 进行封装,以实现线程安全的生产消费队列。

下面是C++实现生产消费队列的示例代码:


#include <queue>

#include <mutex>

#include <condition_variable>

template<typename T>

class ThreadSafeQueue {

public:

  ThreadSafeQueue() {}

  

  void push(T t) {

    std::unique_lock<std::mutex> lock(m_mutex);

    m_queue.push(t);

    m_notEmpty.notify_one();

  }

  

  T pop() {

    std::unique_lock<std::mutex> lock(m_mutex);

    m_notEmpty.wait(lock, [this](){ return !m_queue.empty(); });

    T t = m_queue.front();

    m_queue.pop();

    return t;

  }

  

private:

  std::queue<T> m_queue;

  std::mutex m_mutex;

  std::condition_variable m_notEmpty;

};

上述代码中,ThreadSafeQueue类基于std::queue 进行了封装。它包括了一个私有的std::queue 类型的对象m_queue,一个std::mutex类型的成员变量m_mutex,以及一个std::condition_variable类型的成员变量m_notEmpty。其中,m_mutex用于互斥保护队列m_queue的访问,m_notEmpty用于等待和通知其他线程。

类中的push()函数实现了生产者向队列中生产数据的功能。它首先获取互斥锁m_mutex,然后将数据t添加到队列m_queue的尾部,并通过调用成员函数m_notEmpty.notify_one()向等待的消费者线程发送通知。注意,这里一定要先添加数据再发送通知,否则可能导致数据丢失或者死锁等情况。

类中的pop()函数实现了消费者从队列中消费数据的功能。它首先获取互斥锁m_mutex,然后调用成员函数m_notEmpty.wait()等待队列m_queue中有数据可供消费。这里采用了Lambda表达式进行等待条件的检查,等价于:


  bool pred() { return !m_queue.empty(); }

  m_notEmpty.wait(lock, pred);

当等待条件满足时,pop()函数将从队列m_queue的头部取出一个数据t,并将其从队列中移除。最后,它返回取出的数据t,并释放互斥锁m_mutex。

以上是C++实现生产消费队列的示例代码。在实际应用中,我们还需要进行更多的优化和调试,以确保线程安全的同时,保证队列的性能和可靠性。但是,本文提供的示例代码可以作为一个基础框架,供初学者参考和学习。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复