接上文:线程池的设计(一):半同步半异步线程池的设计
git
领导者追随者模式在使用方式上与半同步半异步模式相同,如下主要介绍不一样的实现部分,相同部分一笔带过。github
本文讲述的只是领导者追随者线程池的一种实现,不得不说,这种模式真的很复杂。 异步
两种模式的主要区别在于任务队列的实现。函数
领导者追随者线程池的工做流程:性能
代码实现:https://github.com/421986908/Leader_Followersspa
1.启动:.net
a.生成一组线程,放入线程数据;线程
2.添加任务:设计
a.任务队列的实现是一个单向链表,添加任务就是向链表的表尾添加一个元素;指针
任务队列的实现:
①. 每个任务的具体定义应包含如下结构:线程函数名、线程函数传入的参数和指向下一个任务的指针。结构体定义以下:
struct job { void* (*callback_function)(void *arg); void *arg; struct job *next; };
②. 新增任务时,一样要先判断queue_cur_num
是否大于max_queue_num,判断线程池和队列是否处于服务的状态。添加任务只要将任务添加到链表的表尾便可,核心代码片断以下:
pjob->callback_function = callback_function; pjob->arg = arg; pjob->next = NULL; if(pool->head == NULL) { pool->head = pool->tail = pjob; } else { pool->tail->next = pjob; pool->tail = pjob; }
工做者线程在结束任务后,会继续进入wait状态,至关于从新进入排队。此例中的任务队列能够类比于机场打车时的乘客队列,而工做者线程就至关于出租车。
③. 工做者线程wait到新任务时,会首先进行任务队列的操做,即转换领导者的身份,选出单链表表头的下一位为领导者,同时要注意维护队列的长度queue_cur_num
,核心代码片断以下:
pool->queue_cur_num--; pjob = pool->head; if(pool->queue_cur_num == 0) { pool->head = pool->tail = NULL; } else { pool->head = pjob->next; }
3.中止:等待全部线程结束后中止线程池。
关于领导者追随者线程池问答:
1.相比半同步半异步线程池,领导者追随者的优点在哪里? 不用进行线程间的上下文切换,性能获得提升。
T(L/F)=T(多路分离)+T(分配)+T(处理)+T(同步)+T(上下文)
T(H/H)=T(多路分离)+T(分配)+T(处理)+T(同步)+T(数据传递)+T(上下文)
参照文档:
《领导者/追随者》http://blog.csdn.net/hzhsan/article/details/25018167