c++11 线程池学习笔记 (一) 任务队列

学习内容来自一下地址

http://www.cnblogs.com/qicosmos/p/4772486.html

github https://github.com/qicosmos/cosmos

 

主要使用c++11的多线程编程的互斥 同步等功能 编写一个生产消费者队列 用于任务的传递

将任务的接受处理进行分离 更加简洁 易于处理和扩展修改

template<typename T> //队列传递的元素  为了适配更多情况 这里使用了模板
class SyncQueue {
...................
}

 

 

//初始化函数 定义队列最大可容纳元素数目和停止表示

SyncQueue(int maxSize):m_maxSize(maxSize),m_needStop(false){}

 

//Put函数即是提价元素 之所以使用两种函数 是考虑左值和右值 提高元素拷贝效率

void Put(const T& x) {
Add(x);
}
void Put(T&& x) {
Add(std::forward<T>(x));
}

 

//查看Add函数

template<typename F>
void Add(F&& x) {
std::unique_lock<std::mutex> locker(m_mutex);   //加锁
m_notFull.wait(locker, [this] {return m_needStop || NotFull(); }); // 使条件变量等待 队列未满或者标记停止标识
if (m_needStop) //停止退出
return;
m_queue.push_back(std::forward<F>(x));  //则将元素添加进容器
m_notEmpty.notify_one();
}
//加锁情况下 使条件变量等待 队列未满或者标记停止标识 则将元素添加进容器或者停止退出

 

//元素取出函数 一个是取出容器内全部元素 一个是取出单个元素

void Take(std::list<T>& list) 

void Take(T& t) 

//void Take(std::list<T>& list) 取出容器内全部元素 直接将容器去除 并清除队列内的容器

//代码里直接使用了move函数  并notify Take函数中的条件变量

void Take(std::list<T>& list) {
std::unique_lock<std::mutex> locker(m_mutex);
m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });
if (m_needStop)
return;
list = std::move(m_queue);
m_notFull.notify_one();
}

//void Take(T& t) 加锁情况下 使用条件变量等待停止标识或者容器非空
//将容器内元素弹出 并notify Add函数中的条件变量

void Take(T& t) {
std::unique_lock<std::mutex> locker(m_mutex);
m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });
if (m_needStop)
return;
t = m_queue.front();
m_queue.pop_front();
m_notFull.notify_one();
}

 

源码如下 (仅仅队列代码,测试代码将同线程池一同测试)

 1 #pragma once
 2 
 3 #include <list>
 4 #include <mutex>
 5 #include <thread>
 6 #include <condition_variable>
 7 #include <iostream>
 8 
 9 using namespace std;
10 
11 template<typename T>
12 class SyncQueue {
13 public:
14     SyncQueue(int maxSize):m_maxSize(maxSize),m_needStop(false){}
15     void Put(const T& x) {
16         Add(x);
17     }
18     void Put(T&& x) {
19         Add(std::forward<T>(x));
20     }
21     void Take(std::list<T>& list) {
22         std::unique_lock<std::mutex> locker(m_mutex);
23         m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });
24         if (m_needStop)
25             return;
26         list = std::move(m_queue);
27         m_notFull.notify_one();
28     }
29 
30     void Take(T& t) {
31         std::unique_lock<std::mutex> locker(m_mutex);
32         m_notEmpty.wait(locker, [this] {return m_needStop || NotEmpty(); });
33         if (m_needStop)
34             return;
35         t = m_queue.front();
36         m_queue.pop_front();
37         m_notFull.notify_one();
38     }
39 
40     void Stop() {
41         {
42             std::lock_guard<std::mutex> locker(m_mutex);
43             m_needStop = true;
44         }
45         m_notFull.notify_all();
46         m_notEmpty.notify_all();
47     }
48 
49     bool Empty() {
50         std::lock_guard<std::mutex> locker(m_mutex);
51         return m_queue.empty();
52     }
53 
54     bool Full() {
55         std::lock_guard<std::mutex> locker(m_mutex);
56         return m_queue.size() == m_maxSize;
57     }
58 
59     size_t Size() {
60         std::lock_guard<std::mutex> locker(m_mutex);
61         return m_queue.size();
62     }
63 
64     int Count() {
65         return m_queue.size();
66     }
67 private:
68     bool NotFull()const {
69         bool full = m_queue.size() >= m_maxSize;
70         if (full)
71             cout << "buffer area is full,wait..." << endl;
72         return !full;
73     }
74     bool NotEmpty()const {
75         bool empty = m_queue.empty();
76         if (empty)
77             cout << "buffer area is empty,wait... " << 
78                 " threadID: " << this_thread::get_id() <<endl;
79         return !empty;
80     }
81 
82     template<typename F>
83     void Add(F&& x) {
84         std::unique_lock<std::mutex> locker(m_mutex);
85         m_notFull.wait(locker, [this] {return m_needStop || NotFull(); });
86         if (m_needStop)
87             return;
88         m_queue.push_back(std::forward<F>(x));
89         m_notEmpty.notify_one();
90     }
91 private:
92     std::list<T> m_queue;
93     std::mutex m_mutex;
94     std::condition_variable m_notEmpty;
95     std::condition_variable m_notFull;
96     int m_maxSize;
97     bool m_needStop;
98 };
View Code

 

posted on 2018-02-19 20:46  itdef  阅读(1281)  评论(0编辑  收藏  举报

导航