(2) 工作线程的任务执行流程
for(;;) { // 检查任务队列是否有任务要运行 if( !CheckTaskQueue() ) { // 队列中没有任务 pPool->OnTaskIdle( this ); // 通知线程池,此线程已经空闲 if( WaitForTask() ) continue;// 继续循环 else return 0;// 终止线程 } else { // 有任务需要运行 pTask = GetTask(); // 取得新任务 try { while( !pTask->Run() ) { // 此处循环体为空,不断运行直到任务执行完毕 } } catch( … ) { WriteLog( … ); // 执行任务时产生异常,记录入日志 } delete pTask; // 任务执行完毕,删除此任务 } } |
在任务执行的核心部分,使用了try-catch控制块进行异常捕获。虽然异常会对程序速度有很略微的影响,但是因为要执行的任务是未知的,不能保证任务可以正常执行。因为一个任务的异常而导致服务器的服务程序崩溃,这是绝对不允许的。使用异常捕获不仅可以保证服务器流程的顺利执行,而且把异常信息存入日志文件,还可以跟踪错误。
性能测试
为了检验此线程池的性能是否和预期相同,并且分析出线程池的不同参数配置对系统性能的影响,特编写了测试程序对三组参数进行了测试,测试结果如图1所示:
|
横坐标是任务数量;纵坐标是消耗时间,以秒(s)为单位。
参数1:N2 = 1, N5 = 1; 参数2:N2 = 5, N5 = 1; 参数3:N2 = 5, N5 = 5
测试中,系统的总的线程数限制为500,任务都是5ms。这里只针对N2和N5进行测试,N2是平均情况下系统每次向线程池中增加的任务数量,N5是每个线程一次执行任务数量。
在任务量比较小的情况下,三者的对系统性能的占用基本上相等。但是当任务量很巨大的时候,参数1比参数2效率要稍微高出一些,而参数3的执行效率几乎是前两者的一倍。
因为都是轻量级任务,所以N2的变化对系统效率的影响并不大,而N5的影响就很显著。
结束语
通过测试可以看出,在服务器中使用线程池后,并不意味着系统性能就一定可以提升。不同系统的任务有着各自不同的特点,这就需要根据服务器任务的特点进一步调整缓冲池的一些关键参数,才能最大程度的提高系统效率。这些参数就是上面分析过程中的N1、N2、N3、N4、N5、n1、n2、n3。