共享队列的线程安全性

时间:2018-10-23 16:21:41

标签: c++ multithreading queue

我对C ++中的多线程应用程序没有太多的经验,我目前正在尝试设计一个具有四个线程和三个共享队列的应用程序。这将是我一年前用Python编写的应用程序的C ++版本,但运行速度不足以满足新要求(无论如何,我一直想学习C ++中的多线程,所以这似乎是个好机会)。

计划的线程是:

1)用于从文件末尾刮行的线程(等同于在Linux CL中运行tail -f)

2)线程处理文件中的行

3)用于将处理过的行发送到其他地方的线程

4)可选线程,用于在日志文件中写入调试输出(是否在运行时指定使用该输出)

我打算使用的队列设置是:

线程1和2之间有一个共享队列;线程1放入项目,线程2取出项目。永不相反。线程2和3的一个共享队列的行为与前者相同。第三个可选队列由前三个线程全部写入,并由第四个线程读取。

我遇到的问题是,与Python中的multiprocessing.Queue()对象不同,C ++队列默认情况下不是线程安全的,而且我还没有找到标准的共享队列实现。

问题:

1)是否可以在C ++中重新使用我在Python中使用的基本轮廓(上面)而不会陷入混乱呢?

2)是否有我尚未找到的线程安全队列的标准实现,还是我不得不求助于外来库(例如Boost)还是自己创建?

1 个答案:

答案 0 :(得分:1)

如果您不想使用升压,那么这里的实现或多或少是完整的:

#include <mutex>
#include <condition_variable>
#include <queue>

class Queue
{
public:
  Queue() = default;
  ~Queue() = default;

  int pop()
  {
    std::unique_lock<std::mutex> lock_guard(mutex_);

    while (internal_queue_.empty())
    {
      cond_.wait(lock_guard);
    }

    auto item = i_queue_.front();
    i_queue_.pop();
    return item;
  }

  void push(int item)
  {
    std::unique_lock<std::mutex> lock_guard(mutex_);
    i_queue_.push(item);
    lock_guard.unlock();
    cond_.notify_one();
  }

private:
  std::queue<int> i_queue_;
  std::mutex mutex_;
  std::condition_variable cond_;
};

int main()
{
  Queue queue;
  queue.push(1);
  auto i = queue.pop();
  return 0;
}

请注意,pop将阻塞您的线程,直到队列为空。推送将通知正在等待的线程。也就是说,您只需要在线程中循环就可以一对一地弹出项目。如果没有更多的物品可消费了,循环将处于等待状态。