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变量 左值右值

  • 相关阅读:
    左旋转字符串
    swoole(8)http服务
    整数反转
    两数之和
    广度优先搜索
    快速排序
    JavaScript当中的eval函数
    JavaScript中的作用域链原理
    git push和git pull
    cherry-pick,revert和rebase使用的3-way合并策略
  • 原文地址:https://www.cnblogs.com/itdef/p/4593147.html
Copyright © 2011-2022 走看看