前言:
目前网上的
c++线程池
资源多是使用老版本或者使用系统接口实现,使用c++ 11新特性的不多,最近研究了一下,实现一个简单版本,可实现任意任意参数函数的调用以及获得返回值。
0 前置知识
首先介绍一下用到的c++新特性
- 可变参数模板:利用这一特性实现任意参数的传递
- bind函数,lambda表达式: 用于将带参数的函数封装为不带形参和无返回值的函数,统一接口
- forward: 完美转发,防止在函数封装绑定时改变形参的原始属性(引用,常量等属性)
- shared_ptr, unique_ptr:智能指针,程序结束自动析构,不用手动管理资源,省心省力
- thread:c++11 引入的多线程标准库,完美跨平台
- future:期物,用于子线程结束后获取结果
- package_task: 异步任务包装模板,可以包装函数用于其它线程.有点类似与function
- function: 函数包装模板库,可以理解为将不同类型但形参和返回值相同的函数统一的接口
- queue,vecort: 向量,队列
- mutex: c++ 11引入的互斥锁对象
- condition_variable: c++ 11引入的条件变量,用于控制线程阻塞
- atmoic:原子变量,++,--,+=,-=这些操作时原子类型的,防止读取写于入失败
1 理论知识
问题0:线程运行完函数后自动就被系统回收了,怎么才能实现复用呢
答:刚开始我也是比较疑惑,以为有个什么状态方法可以调用,在线程结束被销毁前阻塞住,从而接取下一个任务,实现复用,其实并非如此,线程池实现的原理是,让线程执行一个死循环任务,当任务队列为空时,就让他阻塞防止资源浪费,当有任务时,解除阻塞,让线程向下执行,当执行完当前函数后,又会再次运行到死循环的的上方,继续向下执行,从而周而复始的不断接任务--完成任务--接任务的循环,这里可以设置一个变量来控制,当想销毁线程池的时候,让死循环不再成立,当该线程执行完当前函数后,退出循环,从而销毁线程,思路很精妙