1. 程式人生 > 實用技巧 >生產者與消費者

生產者與消費者

多執行緒實現生產者與消費者

#pragma once
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>

 class ProAndConClass
{
public:
    ProAndConClass();
    ~ProAndConClass();
    void printThread();
    void addThread(int num);
    bool g_flag = false;
    ProAndConClass
* getInstance() { return &instance; } private: static ProAndConClass instance; std::condition_variable g_cond_add_enable; //計算條件變數 std::condition_variable g_cond_print_enable;//列印條件 std::mutex g_mutex; int g_value = 0; bool g_print_able = false; //是否可以列印 }; //.cpp檔案
#include "ProduceAndConsume.h" //若不在堆上建立類的例項。 //需要定義在全域性區,不能放在類的內部,類成員變數可能分配在堆或者棧上 //執行緒是不會共享棧區的 //std::condition_variable g_cond_add_enable; //計算條件變數 //std::condition_variable g_cond_print_enable;//列印條件 //std::mutex g_mutex; //int g_value = 0; //bool g_print_able = false; //是否可以列印 ProAndConClass::ProAndConClass() { } ProAndConClass::
~ProAndConClass() { } void ProAndConClass::addThread(int numThread) { std::cout << "add thread begin" << std::endl; while (g_value < numThread) { std::unique_lock<std::mutex>my_lock(g_mutex); g_cond_add_enable.wait(my_lock, [=] { return !g_print_able; }); g_value++; g_print_able = true; std::cout << "++add thread" << g_value << std::endl; g_cond_print_enable.notify_one(); //增加列印 } //g_flag = false; std::cout << "add thread leave"<<std::endl; } void ProAndConClass::printThread() { std::cout << "print thread begin" << std::endl; while (g_flag) { std::unique_lock<std::mutex> my_lock(g_mutex); g_cond_print_enable.wait(my_lock, [=] { return g_print_able; }); g_print_able = false; std::cout << "-- print thread" << g_value << std::endl; g_cond_add_enable.notify_one();//通知增加執行緒 } std::cout << "print thread leave" << std::endl; } //main void testProAndCon() { ProAndConClass*proandcon=new(std::nothrow)ProAndConClass(); proandcon->g_flag = true; /*ProAndConClass proandcon;//如此,需要把變數定義到全域性資料段.因為這種形式物件構造在棧區,而執行緒獨享棧區 proandcon.g_flag = true;*/ //執行緒的初始化三種方式:普通函式、類成員函式、函式物件 std::thread thread_add(&ProAndConClass::addThread, proandcon, 10); // 生產者 std::thread thread_print(&ProAndConClass::printThread, proandcon); //消費者 //getchar(); Sleep(1000); if (thread_add.joinable()) { std::cout << "join add thread" << std::endl; thread_add.join(); } if (thread_print.joinable()) { std::cout << "join print thread" << std::endl; thread_print.join(); } return; }