├── Cpp11ThreadPool
├── Main.cpp
├── threadpool.h
├── Cpp11ThreadPool.vcxproj.filters
└── Cpp11ThreadPool.vcxproj
├── Cpp11ThreadPool.sln
└── README.md
/Cpp11ThreadPool/Main.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wanttobeno/Cpp11ThreadPool/HEAD/Cpp11ThreadPool/Main.cpp
--------------------------------------------------------------------------------
/Cpp11ThreadPool/threadpool.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wanttobeno/Cpp11ThreadPool/HEAD/Cpp11ThreadPool/threadpool.h
--------------------------------------------------------------------------------
/Cpp11ThreadPool.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.21005.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cpp11ThreadPool", "Cpp11ThreadPool\Cpp11ThreadPool.vcxproj", "{B91CA619-DF0D-4FBE-8410-039D336771BD}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Win32 = Debug|Win32
11 | Release|Win32 = Release|Win32
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {B91CA619-DF0D-4FBE-8410-039D336771BD}.Debug|Win32.ActiveCfg = Debug|Win32
15 | {B91CA619-DF0D-4FBE-8410-039D336771BD}.Debug|Win32.Build.0 = Debug|Win32
16 | {B91CA619-DF0D-4FBE-8410-039D336771BD}.Release|Win32.ActiveCfg = Release|Win32
17 | {B91CA619-DF0D-4FBE-8410-039D336771BD}.Release|Win32.Build.0 = Release|Win32
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/Cpp11ThreadPool/Cpp11ThreadPool.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
23 |
24 | Header Files
25 |
26 |
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # C++ 11 Threadpool
2 |
3 | 学习C++ 11时遇到的一个线程池,使用了很多C++ 11的新特性,
4 | 流程和传统的差不多,但是代码简洁了很多。
5 |
6 |
7 | [From lzpong github](https://github.com/lzpong/threadpool)
8 |
9 | ---
10 | based on C++11 , a mini `threadpool` , accept variable number of parameters.
11 | 基于C++11的线程池,简洁且可以带任意多的参数
12 |
13 | 管理一个任务队列,一个线程队列,然后每次取一个任务分配给一个线程去做,循环往复。
14 | 有意思的是,限制只创建一个线程,这样就是一个完全的任务队列了。
15 |
16 | 线程池,可以提交变参函数或拉姆达表达式的匿名函数执行,可以获取执行返回值
17 |
18 | 代码不多,**上百行代码就完成了 线程池**, 并且, 看看 `commit`, 哈, 不是固定参数的, 无参数数量限制! 这得益于可变参数模板.
19 |
20 |
21 |
22 | *为了避嫌,先进行一下版权说明:代码是 me “写”的,但是思路来自 Internet, 特别是[这个线程池实现](https://github.com/progschj/ThreadPool)(基本 copy 了这个实现,加上[这位同学的实现](http://blog.csdn.net/zdarks/article/details/46994607)和解释,好东西值得 copy ! *
23 | **然后综合更改了下,更加简洁**
24 | *)。*
25 |
26 | ##C++11语言细节
27 | 即使懂原理也不代表能写出程序,上面用了众多c++11的“奇技淫巧”,下面简单描述之。
28 |
29 | 1. using Task = function 是类型别名,简化了 typedef 的用法。function 可以认为是一个函数类型,接受任意原型是 void() 的函数,或是函数对象,或是匿名函数。void() 意思是不带参数,没有返回值。
30 | 2. pool.emplace_back([this]{...}) 和 pool.push_back([this]{...}) 功能一样,只不过前者性能会更好;
31 | 3. pool.emplace_back([this]{...}) 是构造了一个线程对象,执行函数是拉姆达匿名函数 ;
32 | 4. 所有对象的初始化方式均采用了 {},而不再使用 () 方式,因为风格不够一致且容易出错;
33 | 5. 匿名函数: [this]{...} 不多说。[] 是捕捉器,this 是引用域外的变量 this指针, 内部使用死循环, 由cv_task.wait(lock,[this]{...}) 来阻塞线程;
34 | 6. delctype(expr) 用来推断 expr 的类型,和 auto 是类似的,相当于类型占位符,占据一个类型的位置;auto f(A a, B b) -> decltype(a+b) 是一种用法,不能写作 decltype(a+b) f(A a, B b),为啥?! c++ 就是这么规定的!
35 | 7. commit 方法是不是略奇葩!可以带任意多的参数,第一个参数是 f,后面依次是函数 f 的参数(*注意:参数要传struct/class的话,建议用pointer,小心变量的作用域*)! 可变参数模板是 c++11 的一大亮点,够亮!至于为什么是 Arg... 和 arg... ,因为规定就是这么用的!
36 | 8. commit 直接使用智能调用stdcall函数,但有两种方法可以实现调用类成员,一种是使用 bind: .commit(std::bind(&Dog::sayHello, &dog)); 一种是用 mem_fn: .commit(std::mem_fn(&Dog::sayHello), &dog);
37 | 9. make_shared 用来构造 shared_ptr 智能指针。用法大体是 shared_ptr p = make_shared(4) 然后 *p == 4 。智能指针的好处就是, 自动 delete !
38 | 10. bind 函数,接受函数 f 和部分参数,返回currying后的匿名函数,譬如 bind(add, 4) 可以实现类似 add4 的函数!
39 | 11. forward() 函数,类似于 move() 函数,后者是将参数右值化,前者是... 肿么说呢?大概意思就是:不改变最初传入的类型的引用类型(左值还是左值,右值还是右值);
40 | 12. packaged_task 就是任务函数的封装类,通过 get_future 获取 future , 然后通过 future 可以获取函数的返回值(future.get());packaged_task 本身可以像函数一样调用 () ;
41 | 13. queue 是队列类, front() 获取头部元素, pop() 移除头部元素;back() 获取尾部元素,push() 尾部添加元素;
42 | 14. lock_guard 是 mutex 的 stack 封装类,构造的时候 lock(),析构的时候 unlock(),是 c++ RAII 的 idea;
43 | 15. condition_variable cv; 条件变量, 需要配合 unique_lock 使用;unique_lock 相比 lock_guard 的好处是:可以随时 unlock() 和 lock()。 cv.wait() 之前需要持有 mutex,wait 本身会 unlock() mutex,如果条件满足则会重新持有 mutex。
44 | 16. 最后线程池析构的时候,join() 可以等待任务都执行完在结束,很安全!
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Cpp11ThreadPool/Cpp11ThreadPool.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {B91CA619-DF0D-4FBE-8410-039D336771BD}
15 | Win32Proj
16 | Cpp11ThreadPool
17 | 10.0.16299.0
18 |
19 |
20 |
21 | Application
22 | true
23 | v120_xp
24 | Unicode
25 |
26 |
27 | Application
28 | false
29 | v120_xp
30 | true
31 | Unicode
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | true
45 |
46 |
47 | false
48 |
49 |
50 |
51 |
52 |
53 | Level3
54 | Disabled
55 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
56 |
57 |
58 | Console
59 | true
60 |
61 |
62 |
63 |
64 | Level3
65 |
66 |
67 | MaxSpeed
68 | true
69 | true
70 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
71 |
72 |
73 | Console
74 | true
75 | true
76 | true
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------