使用c++11,實現一個生產者-消費者模型
阿新 • • 發佈:2019-02-12
#include "stdafx.h" #include "Test.h" #include <process.h> #include <utility> #include <memory> #include <string> #include <iostream> #include <vector> #include <bitset> #include <functional> #include <thread> #include <future> #include <mutex> #include <deque> using namespace std; class CLog { public: void Write(std::string str) { std::unique_lock<std::mutex> lock(mu); std::cout << str << std::endl; } private: std::mutex mu; }; class CMyProduct { public: CMyProduct(unsigned int nId) : m_nProductId(nId) {}; CMyProduct(const CMyProduct& other) { this->m_nProductId = other.m_nProductId; }; CMyProduct(CMyProduct&& other) { this->m_nProductId = other.m_nProductId; }; CMyProduct& operator = (CMyProduct&& other) { this->m_nProductId = other.m_nProductId; return *this; }; CMyProduct& operator = (const CMyProduct& other) { this->m_nProductId = other.m_nProductId; return *this; }; ~CMyProduct() {}; unsigned int GetId() { return m_nProductId; }; void ShowProduct() { cout << m_nProductId << endl; }; private: unsigned int m_nProductId; }; std::deque<CMyProduct> g_dqStores; std::mutex g_mut; std::condition_variable g_CondVar; atomic<int> nMaxNum; class CProducer { public: CProducer(char cID) : m_cID(cID) {}; void Produce() { while (true) { { std::unique_lock<mutex> lock(g_mut); if ((int)g_dqStores.size() > nMaxNum) { g_CondVar.notify_one(); g_CondVar.wait(lock, [] { return g_dqStores.size() <= nMaxNum; }); } static int nIndex = 0; nIndex++; g_dqStores.push_back(std::move(CMyProduct(nIndex))); cout << "Produce " << m_cID << ": " << nIndex << endl; } g_CondVar.notify_one(); this_thread::sleep_for(std::chrono::milliseconds(100)); } }; private: char m_cID; }; class CConsumer { public: CConsumer(char cID) : m_cID(cID) {}; ~CConsumer() {}; void Consume() { int nCount = 0; while (true) { { std::unique_lock<mutex> lock(g_mut); if (g_dqStores.empty()) { g_CondVar.notify_one(); g_CondVar.wait(lock, [] { return !g_dqStores.empty(); }); } CMyProduct product = g_dqStores.at(0); cout << "Consume " << m_cID << ": " << product.GetId() << endl; g_dqStores.pop_front(); nCount++; } this_thread::sleep_for(std::chrono::milliseconds(100)); } }; private: char m_cID; }; int main() { CProducer producer_1('A'); CProducer producer_2('B'); CConsumer consumer_1('C'); ///< future_produce_1 std::future<void> ft_pd_1(std::async(std::launch::async, &CProducer::Produce, producer_1)); ///< future_consume_1 std::future<void> ft_cs_1(std::async(std::launch::async, &CConsumer::Consume, consumer_1)); ///< future_produce_2 std::future<void> ft_pd_2(std::async(std::launch::async, &CProducer::Produce, producer_2)); this_thread::sleep_for(std::chrono::seconds(300)); return 0; }