这是之前有做的一个可以接受用户传入任意类型的任务函数和任意参数,并且能拿到任务对应返回值的一个线程池框架,可以链接成动态库,用在相关项目里面。一共实现了两版,都是支持fixed和cached模式的,半同步半异步的(生产者消费者模型,异步 提交任务,获取任务结果,用future类达到异步)
今天就简单稍微做个小结。
第一版
1、自己实现Any类,用来接收任意函数,和传递参数
2、怎么拿到返回值结果和结果类型?Result类里面 有Any类成员函数get 用来获取函数返回结果,Result构造函数里有Task类型对象,能接收到用户传入参数和类型,通过setvalue设置拿到返回值类型,通过getvalue获取task的返回值,最后返回一个Result类型打包的对象用来接收用户提交任务之后的返回值
3、用继承 重写虚函数的方式,定义Task任务类为抽象基类,用户设置自己的mtask类,自己实现里面run方法(线程怎么工作)
4、自己用mutex和condition_variable实现了信号量类
5、线程池析构,必须等所有线程把工作做完之后再析构
非必现的死锁问题:有时候线程资源释放回收之后会有线程没有回收干净
对于在阻塞队列里面没有拿到锁的休眠线程,和正在工作的线程没有问题;因为少考虑了一种情况,当threadpool要析构的时候,有线程执行完任务,又绕了一圈进到while,阻塞到拿锁那块,当threadpool析构执行到最后面释放锁的时候,因为用的都是一把锁,此时阻塞在锁的那个线程就拿到锁往下执行,但是会执行到notempty wait的地方,因为此时队列里线程还有他的存在,不空,但是析构函数已经走到最后面了,没人唤醒他,他就一直睡死在里面notempty wait这块了
问题就是notempty wait这块没人notify唤醒了,锁加双重判断,和把notify和获取锁代码位置换一下
第二版
简化了代码引入future类和packaged_task打包 , packaged_task 调用get_future 获取 future , 然后通过 future 异步可以获取函数的返回值;使用可变参模板代替Any类
future->我们写的result类