zoukankan      html  css  js  c++  java
  • c++11多线程学习笔记之四 生产消费者

    #ifndef MY_QUEUE_H__
    #define MY_QUEUE_H__
    
    #include<list>
    #include<mutex>
    #include<thread>
    #include<condition_variable>
    #include <iostream>
    
    
    template <typename T>
    class SyncQueue{
    public:
    	SyncQueue(int maxSize = 10)
    		:maxSize_(maxSize), flagStop_(false)
    	{}
    
    	bool IsEmpty()
    	{
    		std::lock_guard<std::mutex> locker(mutex_);
    		return queue_.empty();
    	}
    
    	bool IsFull()
    	{
    		std::lock_guard<std::mutex> locker(mutex_);
    		return queue_.size() == maxSize_;
    	}
    
    	void Stop()
    	{
    		{
    			std::lock_guard<std::mutex> locker(mutex_);
    			flagStop_ = true;
    		}
    		notFull_.notify_all();
    		notEmpty_.notify_all();
    	}
    
    	template<typename F>
    	void Add(F&& x)
    	{
    		std::unique_lock<std::mutex> locker(mutex_);
    		notFull_.wait(locker, [this]{return flagStop_ || queue_.size() < maxSize_; });
    		if (flagStop_)
    			return;
    		queue_.push_back(std::forward<F>(x));
    		notEmpty_.notify_one();
    	}
    public:
    	void Put(const T& x)
    	{
    		Add(x);
    	}
    
    	void Put(T&& x)
    	{
    		Add(std::forward<T>(x));
    	}
    
    	void Take(T& t)
    	{
    		std::unique_lock<std::mutex> locker(mutex_);
    		notEmpty_.wait(locker, [this]{return flagStop_ || !queue_.empty(); });
    		if (flagStop_)
    			return;
    		t = queue_.front();
    		queue_.pop_front();
    		notFull_.notify_one();
    	}
    
    
    private:
    	std::list<T> queue_;
    	std::mutex mutex_;
    	std::condition_variable notEmpty_;
    	std::condition_variable notFull_;
    	int maxSize_;
    	bool flagStop_;
    };
    
    
    #endif//MY_QUEUE_H__
    

      测试代码

    // 111.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "MyQueue.h"
    
    #include <windows.h>
    
    SyncQueue<int> g_queue(15);
    
    void ProduceTask()
    {
    	for (int i = 0; i < 20; i++)
    	{
    		g_queue.Add(i);
    		Sleep(50);
    	}
    }
    
    void ConsumerTask()
    {
    	for (int i = 0; i < 20; i++)
    	{
    		int j = 0;
    		g_queue.Take(j);
    		std::cout << j << " ";
    	}
    	std::cout << std::endl;
    
    	std::cout << "stop now" << std::endl;
    	g_queue.Stop();
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	std::thread producer(ProduceTask); // 创建生产者线程.
    	std::thread consumer(ConsumerTask); // 创建消费之线程.
    	producer.join();
    	consumer.join();
    
    	return 0;
    }
    

      单线程生产 单线程消费  使用了条件变量 互斥量 线程 AUTO变量 左值右值

  • 相关阅读:
    legend2---开发日志8(thinkphp和vue如何配合才能达到最优)
    英雄联盟:英雄台词翻译(我用双手成就你的梦想。)
    js插件---bootstrap插件daterangepicker是什么
    js插件---bootstrap-datepicker.js是什么
    ORDER BY RAND()
    Boost.Asio c++ 网络编程翻译(26)
    3Sum Closest
    hdu3480二维斜率优化DP
    MySQL Study之--Mysql无法启动“mysql.host”
    于PsIsSystemThread无论是在线程系统线程标识获得
  • 原文地址:https://www.cnblogs.com/itdef/p/4593147.html
Copyright © 2011-2022 走看看