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;
    }
  • 相关阅读:
    明白了最基本的压缩原理
    sys.path.insert(0, os.path.join('..', '..', '..', '..','...')) 解释
    《MongoDB权威指南》读书笔记 第二章 入门 (一)
    __str__简单用法
    python 中使用memcache
    《MongoDB权威指南》读书笔记 第三章 创建、更新及删除文档
    __call__ 函数简单用法
    《MongoDB权威指南》读书笔记 第一章 简介
    chr() ord() 的用法
    python 验证数据类型函数
  • 原文地址:https://www.cnblogs.com/huangfuyuan/p/13555471.html
Copyright © 2011-2022 走看看