zoukankan      html  css  js  c++  java
  • 生产者与消费者

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

    【前言】开启两个线程一个生产者一个消费者,操作同一个变量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;
    }
  • 相关阅读:
    【BZOJ4337】[BJOI2015] 树的同构(哈希水题)
    【BZOJ4176】Lucas的数论(杜教筛)
    【BZOJ2627】JZPKIL(数论大杂烩)
    【BZOJ2228】[ZJOI2011] 礼物(巧妙的三部曲)
    【BZOJ2954】[POI2002] 超级马(暴搜)
    【BZOJ4498】魔法的碰撞(动态规划)
    【BZOJ3489】A simple rmq problem(三维数点)
    【BZOJ2626】JZPFAR(KD-Tree)
    【BZOJ4520】[CQOI2016] K远点对(KD-Tree)
    【BZOJ1941】[SDOI2010] Hide and Seek(KD-Tree)
  • 原文地址:https://www.cnblogs.com/huangfuyuan/p/13555471.html
Copyright © 2011-2022 走看看