生产者与消费者
多线程实现生产者与消费者
【前言】开启两个线程一个生产者一个消费者,操作同一个变量g_value 。
1、使用了多线程最重要的三个头文件:mutex、thread、condition_variable;
2、多线程调用类的成员函数的时候,初始化类要注意初始化的位置,多线程是独享栈区,可以分配在堆上,如此那些多线程共同操作的变量可以声明在类内。
#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; }