生产者与消费者

多线程实现生产者与消费者

【前言】开启两个线程一个生产者一个消费者,操作同一个变量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;
}

 

posted @ 2020-08-27 22:49  秋雨声  阅读(244)  评论(0编辑  收藏  举报