1. 程式人生 > 其它 >[C++]生產者消費者模型

[C++]生產者消費者模型

技術標籤:C++# 深入應用C++11

#ifndef STDCONDITION_HPP
#define STDCONDITION_HPP
#include <queue>
#include <chrono>
#include <mutex>
#include <thread>
#include <iostream>
#include <condition_variable>
int test_condition() {
  std::queue<int> produced_nums;
  std::mutex mtx;
  std::condition_variable cv;
  bool notified = false; // 通知訊號
  // 生產者
  auto producer = [&]() {
    for (int i = 0; ; i++) {
      std::this_thread::sleep_for(std::chrono::milliseconds(900));
      std::unique_lock<std::mutex> lock(mtx);
      std::cout << "producing " << i << std::endl;
      produced_nums.push(i);
      notified = true;
      cv.notify_all(); // 此處也可以使用 notify_one
    }

  };
  // 消費者
  auto consumer = [&]() {
    while (true) {
      std::unique_lock<std::mutex> lock(mtx);
      while (!notified) { // 避免虛假喚醒
        cv.wait(lock);
      }
      // 短暫取消鎖,使得生產者有機會在消費者消費空前繼續生產
      lock.unlock();
      std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 消費者慢於生產者
      lock.lock();
      while (!produced_nums.empty()) {
        std::cout << "consuming " << produced_nums.front() << std::endl;
        produced_nums.pop();
      }
      notified = false;
    }
  };
  // 分別在不同的執行緒中執行
  std::thread p(producer);
  std::thread cs[2];
  for (int i = 0; i < 2; ++i) {
    cs[i] = std::thread(consumer);
  }
  p.join();
  for (int i = 0; i < 2; ++i) {
    cs[i].join();
  }
  return 0;
}
#endif // STDCONDITION_HPP