# cartographer线程池(Task和ThreadPool类)的单元测试:thread_pool_test.cc代码笔记
测试1:这里的Receiver类是测试用的,对此忽略
主线程
1、实例化ThreadPool类为pool,其构造函数的输入参数为创建几个线程,并且每一线程均执行ThreadPool::DoWork()函数,开辟副线程。DoWork函数会等待task_queue_存在数据或者ThreadPool::running为false
2、创建task,并通过task::SetWorkItem定义回调函数work_item_,这个回调函数就是线程池处理数据的函数
3、执行ThreadPool::Schedule,将2创建的task放入ThreadPool::tasks_not_ready_
4、执行ThreadPool::SetThreadPool->task::SetThreadPool(ThreadPool),state_ = DISPATCHED, task::thread_pool_to_notify_设为传入的thread_pool;
5、依赖项全部完成后,state_ = DEPENDENCIES_COMPLETED; 执行ThreadPool::NotifyDependenciesCompleted,将task放入task_queue_,这时候task_queue_有数据了,1描述的DoWork函数会继续运行
将ThreadPool::tasks_not_ready_里的task删除
副线程:
1、在主线程5在ThreadPool::task_queue_放入task后,ThreadPool::DoWork()函数结束等待,继续运行
2、取出task_queue_里的task并删除
3、执行thread_pool::Execute->task::Execute:state_ = RUNNING,执行2定义的回调函数,state_ = COMPLETED。
遍历task::dependent_task里是否有依赖于目前task的其他task,无则结束
测试2与测试1一样
测试3:这里的Receiver类是测试用的,对此忽略
主线程:
1、实例化ThreadPool类为pool,其构造函数的输入参数为2,创建两个副线程,并且每一线程均执行ThreadPool::DoWork()函数,开辟副线程。DoWork函数会等待task_queue_存在数据或者ThreadPool::running为false
2、创建两个task:task_1、task_2,并通过task::SetWorkItem定义回调函数work_item_,这个回调函数就是线程池处理数据的函数
3、执行ThreadPool::Schedule:
(1)将2创建的task_1放入ThreadPool::tasks_not_ready_,
(2)执行ThreadPool::SetThreadPool->task::SetThreadPool(ThreadPool),state_ = DISPATCHED, task::thread_pool_to_notify_设为传入的thread_pool;
(3)在这之前没执行过task::AddDependency,则uncompleted_dependencies_为0,没有依赖项,可认为依赖项全部完成。state_ = DEPENDENCIES_COMPLETED;
(4)执行ThreadPool::NotifyDependenciesCompleted,将task_1放入task_queue_(这时候task_queue_有数据了,1描述的DoWork函数会继续运行),
将ThreadPool::tasks_not_ready_里的task删除
4、执行task::AddDependency:
(1)为task_2添加依赖项task_1,记录task_2的uncompleted_dependencies_变量为1,
(2)执行task_1里面的AddDependentTask(task_2),因为主线程在运行时,副线程1也在运行,此时task_1的state值不固定,需要对task_1的state做判断:
1)如果state=COMPLETED,那就意味着task_1已经处理完了,执行task_2的OnDependenyCompleted,uncompleted_dependencies_减1,
判断uncompleted_dependencies_是否为0以及task_2的state是否为DISPATCHED(这里的DISPATCHED是为了标记是否运行过ThreadPool::Schedule,
因为ThreadPool::Schedule也会处理一次task,如果不加个记号,就会处理两次task了),这里明显还没有执行过ThreadPool::Schedule,即3步骤,
故不执行ThreadPool::NotifyDependenciesCompleted
2)如果state!=COMPLETED,那就意味着task_1还未处理完,将task_2放入task_1的dependent_tasks_。
5、如3步骤般对task_2处理。
副线程1:
1、主线程3-(4)在ThreadPool::task_queue_放入task_1后,ThreadPool::DoWork()函数结束等待,继续运行
2、取出task_queue_里的task并删除
3、执行thread_pool::Execute->task::Execute:state_ = RUNNING,执行2定义的回调函数,state_ = COMPLETED。
4、遍历task::dependent_task里是否有依赖于目前task的其他task,如果执行这一步时,主线程4-(2)-2)将task_2放入task_1的dependent_tasks_中了,
则调用task_2的OnDependenyCompleted,并执行ThreadPool::NotifyDependenciesCompleted将task_1放入task_queue_(这时候task_queue_有数据了,1描述的DoWork函数会继续运行),
将ThreadPool::tasks_not_ready_里的task删除
副线程2:
1、主线程5或在副线程1完成后,在ThreadPool::task_queue_放入task_2后,ThreadPool::DoWork()函数结束等待,继续运行
2、取出task_queue_里的task并删除
3、执行thread_pool::Execute->task::Execute:state_ = RUNNING,执行2定义的回调函数,state_ = COMPLETED。
遍历task::dependent_task里是否有依赖于目前task的其他task,无则结束。