线程池的优化设计 线程池的优化设计

线程池的优化设计

  • 期刊名字:四川大学学报(自然科学版)
  • 文件大小:757kb
  • 论文作者:赵海,李志蜀,韩学为,叶浩
  • 作者单位:四川大学计算机学院
  • 更新时间:2020-09-29
  • 下载次数:
论文简介

2005年2月四川大学学报(自然科学版)Feb.2005第42卷第1期Journal of Sichuan University (Natural Science Edition)Vol.42 No.1文章编号:0490-6756(2005)01-0063-05线程池的优化设计赵海,李志蜀,韩学为,叶浩(四川大学计算机学院,成都610064)摘要:在各种业务解决方案的设计中,服务器处理任务的效率是衡量方案优劣的一个重要标准.使用线程池技术并发处理任务是提高服务器效率的一个主要手段.在几乎所有线程池的设计中,线程的算法都没有根据线程所要执行的任务特点进行调整,导致实际使用过程中的效率并不高.作者设计了一个通用的线程池,并且可以根据不同任务的特点,调整线程池参数,最大幅度地提高系统性能.关键词:多线程;阻塞;线程池;任务;量级中图分类号:TP391文献标识码:A1引言在各种业务解决方案的设计过程中,服务器处理任务的效率往往决定了方案的成败.使用线程池技术处理任务是提高服务器效率的主要手段,它提高了对服务器资源的利用,使得任务可以并发处理.线程池是预先创建线程的一种技术. 线程池在还没有任务到来之前,创建-定数量(N1)的线程 ,放人空闲队列中.这些线程都是处于睡眠(Sleep)状态,不消耗CPU,但占用较小的内存空间.当任务到来后,缓冲池给次任务分配-个空闲线程,把任务传人此线程中运行.当N1个线程都在处理任务后,缓冲池自动创建- -定数量的新线程,用于处理更多的任务.当系统比较空闲时,大部分线程都一直处于暂停状态,线程池自动销毁-部分线程,回收系统资源.在大多数情况下,不同业务中服务器处理的任务的特点都是不相同的.如果单个任务很复杂却采用一个线程处理多个任务的策略,那么单个任务在处理过程中会因为长时间占用-一个线程 ,而延长任务的响应速度.如果单个任务比较简单却采用一个线 程处理一个任务的策略,那么频繁的给任务分配线程也会导致系统利用率降低.线程池的设计,不仅要实现线程的分配功能,还要根据任务特点调整分配过程的分配算法,增加可移植性,减少重复开发.设计中需要考虑的重点是:(1)任务对象的通用性; (2)线程创建和销毁策略;(3)任务的分配策略.2算法分析与设计2.1任 务对象的通用性不同的业务解决方案有各自独特的任务处理方法,任务的划分上也就千差万别.为了使得在处理任务对象时达到一定程度的通用性,任务对象的设计必须与实际任务的处理逻辑完全无关.从任务执行的角度看,任务不过是处理流程的一次或多次的执行过程,可中国煤化工class Task°TYHCNMHG收稿日期:2004-07-01作者简介:赵海(1981 - ) ,男,2003级硕士研究生.54四川大学学报(自然科学版)第42卷{public:Task();virtual ~ Task();virtual bool run() = 0;};Task类是所有任务类的基类,其中的纯虚函数run( )是任务流程的人口,工作线程在处理任务的时候就从此处开始执行任务的处理流程.设计--个新的任务时,只需要继承Task接口,新的任务就可以放入线程池中执行.任务的创建、执行和销毁设计:(1)任务在其需要的时候才创建,任务的创建通过new操作,动态创建具体的任务对象,然后传人线程池,由线程池自动分配线程来执行此任务;(2)任务是否执行完毕由其自身来决定,一个未知任务什么时候执行完毕是不可能预测的,必须由任务本身来决定,这个策略通过Task: :run()的返回值来实现.当工作线程执行一次任务时,如果返回值为true, 表示任务执行完毕,就用delete操作销毁此任务;如果返回值为false,表示任务需要执行的工作并未完成,继续执行此任务.这样的策略,使得在设计新的任务处理流程时,不需要过多的关心任务的接口规范,只需要在新任务类的构造函数中初始化各种资源,在新任务类的析构函数中回收资源,在run()方法中实现主要的处理逻辑,那么新的任务类即可在线程池中执行.2.2线程的创建与销毁分析线程缓冲池中的维持线程数量按照任务处理的需求来定.在缓冲池刚刚建立时,线程池中有一定数量(N;)的已创建好的线程,这样可以使得新任务可以及时的得到执行.比如,某客户端在向服务器发送登陆请求时,这样一个请求使得服务器通常需要创建好几个相互有关联的任务.也就是说,客户端与服务器端的-次交互,通常会产生- -定数量的任务.根据一个服务器所处理的业务,估计出平均情况下,- -次业务产生的任务数量N2.那么N1应该是N2的整数倍, N;= N2 X n,减少由于线程不够而再创建线程的概率,才能使得服务器在业务处理初期最为高效.在线程缓冲池中的所有线程都处于繁忙状态的时候,线程池就会创建新的线程(设创建N3个).由以上分析,为了减少由于线程不够而再创建线程的概率,N3也应该是N2的整数倍,N3=N2X n2.当服务器业务减少,出现大量线程闲置的情况,就应该销毁-部分线程.很显然,这里应该使用超时策略,当某些线程在超过时间T仍然处于闲置状态,就销毁一部分 空闲线程.设销毁Ns个空闲线程,为了减少由于线程不够而再创建线程的概率, N4也应该是N2的整数倍,N4=N2Xn3.当然,为了使得新任务及时得到处理,即使服务器一直处于空闲,也应该保留N;个线程.2.3任务分配算法分析在业务处理中,会有各种各样的任务对象,这些业务对象对系统资源的使用也不同.这些任务,无论其空间复杂度如何,从线程执行任务这一角度来看,应该关心的主要是时间复杂度.线程缓冲池在接收到新任务的时候,首先要寻找空闲线程,传人新任务,然后执行任务,最后还要删除任务,置空闲线程的标志.寻找空闲线程、传人任务、最后的清理工作,这些都是为了执行任务而产生的额外开销,如果所执行的任务大多数都是轻量级任务,那么额外开销带来的资源浪费就显得很突出了.为了解决这个问题,可以给-一个线程传人Ns个轻量级任务,这-一个线程依次执行Ns个轻量级任务,由于都是在很短时间内完成,并不影响任务响应的及时性.显然,Ns≥中国煤化工3实现TYHCNMHG由于源代码的篇幅关系,并不能把所有代码--列举,这里以伪代码的形式给出线程缓冲池在线程的第1期赵海等:线程池的优化设计6创建、销毁、任务分配以及任务执行方面的流程.(1)线程池任务分配主循环(也是一个线程)这里除了任务分配算法外也包括了部分线程的创建与销毁的算法.for(;;) {pThread = GetIdleThread(); // 检查空闲线程队列if( pThread! = NULL) {if( CheckNewTask() ){ // 有新任务TaskList tl;GetTask( tl ); // 取得- -定 数量的任务AddTaskToThread( pTask, tl ); // 把任务传人线程continue; // 继续循环}if (pThread == NULL & & nThread < THREAD-MAX ) //股 有空闲线程了CreateNewThread(); // 创建新线程Continue; // 继续循环//没有要处理的任务或者已经到达线程数的上限,进入超时等待if( WaitForTaskOrThreadTimeout() ) {if( IncrldleTime() ) > IDLE-MAX) { // 系统空闲,计时//系统长时间处于空闲,销毁-定数量的空闲线程DecrIdleThread();elseretumn0; // 线程终止(2)工作线程的任务执行流程for(;) {//检查任务队列是否有任务要运行if( ! CheckTaskQueue() ) { // 队列中没有任务pPool - >OnTaskIdle( this ); // 通知线程池,此线程已经空闲if( WaitForTask() )return0; // 终止线程} else { //有任务需要运行pTask = GetTask(); // 取得新任务中国煤化工try {while( ! pTask- >Run() ){MYHCNMHG.//此处循环体为空,不断运行直到任务执行完毕6四川大学学报(自然科学版)第42卷cach(-.) {WrteLog(-.); // 执行任务时产生异常,记录人日志delete pTask; // 任务执行完毕,删除此任务}在任务执行的核心部分,使用了try-catch控制块进行异常捕获.虽然异常会对程序速度有很微的影响,但是因为要执行的任务是未知的,不能保证任务可以正常执行.因为一个任务的异常而导致服务器的服务程序崩溃,这是绝对不允许的.使用异常捕获不仅可以保证服务器流程的顺利执行,而且把异常信息存入日志文件,还可以跟踪错误.4性能分析为了检验此线程池的性能是否和预期相同,并且分析出线程池的不同参数配置对系统性能的影响,特编写了测试程序对3组参数进行了测试,测试结果如附图所示.横坐标是任务数量;纵坐标是消耗时间,以秒(s)为单位.60「参数1:N2=1, Ns=1;参数2:N2=5, Ns=1;50 t一参数1参数3:N2=5, Ns=5.测试中,系统的总线程数限制40 t一参数2言30一参数:3为500,任务都是5ms.这里只针对N2和Ns进行测试,N2是平均情况下系统每次向线程池中增加的任纯20务数量, Ns是每个线程一次执行任务数量.0t参数1和参数2代表的是传统的线程池,对于相204000200005000同的任务,他们都采用固定不变的策略来执行任务;而参数3代表的是可调整的线程池,经过分析并调整线任务数量(个)程池的参数后,把系统性能调整到了最佳状态.附图3 组不同参数的线程池性能测试结果在任务量比较小的情况下,三者对系统性能的占Add Fig. The performance c∞ompares of three thread pool用基本上相等.但是当任务量很巨大时(500000个任with different pararneters务),参数3的所用时间是参数1的55.3% ,是参数2的47.8% ,执行效率几乎是前两者的一倍.系统每次产生5个任务时,参数1的线程池会执行5次查找空闲线程的操作和5次分配任务的动作,参数2的线程池会执行1次查找空闲线程操作和5次分配任务动作,而参数3的线程池只会执行1次空闲线程的查找和1次线程的分配动作.虽然执行任务的时候,参数1和参数2是并行执行任务而参数3是依次执行5个任务,但是任务都是轻量级的,执行任务的时间比较短,在空闲线程的查找和任务的分配上面耗费的时间占很大比重.由此可见,参数3之所以比前两者快很多,就在于参数3针对任务的轻量级特点来调整线程池的分配策略,减少线程的查找和任务分配次数,极大地提高了系统的利用率.5结束语中国煤化工MYHCNMHG通过测试可以看出,在服务器中使用线程池后,必须要根据任务特点对线程池的分配算法进行调整,才能更进- -步提高系统的利用率.这些参数就是上面分析过程中的NI,N2,N3,N4,Ns,n1,n2,n3.第1期赵海等:线程池的优化设计6从理论.上说,影响线程池性能还不只这些.比如单CPU环境和多CPU环境对线程的执行效果并不相同线程的创建销毁算法就要进一步调整. 而且实际系统中,任务的量级很不平均,可以考虑对各个任务加上量级的权值评估,这就需要对线程的任务分配和执行进行更进-步的研究.参考文献:[1] Jeffrey Richter 著.王建华,侯丽坤,等译. Windows 核心编程(第四版)[M].北京:机械工业出版社,2000.[2] Bjarne Stroustrup蓍.裘宗燕译.C+ +程序设计语言(特别版)[M].北京:机械工业出版社,2002.[3] Sott Meyers著.侯捷译. EffectiveC+ + 2*[M].武汉:华中科技大学出版社,2001.[4] Jim Beveridge, Robert Wiener著侯捷译. Win32多线程程序设计[M].武汉:华中科技大学出版社,2002.[5] Deepak Alur, Dan Malls, John Crupi著.牛志奇译. J2EE核心模式[M].北京:机械工业出版社,2002.[6] Herb Sutter著.卓小涛译. Exceptional C+ + [M].北京:中国电力出版社,2003.[7] Bruce FEckel. C+ +编程思想(英文原版第二版)[M].北京:机械工业出版社,2002.[8] Andrew s著.潘爱民译.计算机网络(第四版)[M].北京:清华大学出版社, 2004.Optimizing in the Design of Thread PoolZHAO Hai, LI Zhishu, HAN Xue-rwei, YE Hao(College of Computer Science, Sichuan University, Chengdu 610065 ,China)Abstract: In the designs of various kinds of business solutions, the efficiency of processing tasks in the serveris an important standard to weight these solutions. A main means to improve the efficiency is to adopt threadpooling technology to process task concurrently. But the algorithm of most thread pool is not based on thecharacteristic of tasks. As a result, the efficiency of system is improved scarcely. An extensible thread pool is .designed in the thesis. It can be set up the corresponding parameters according to the different characteristicof processing tasks in different server. And in this way the improvement of server performance will be themost enormous.Key words: multithreading; suspend; thread pool; task; weight中国煤化工MYHCNMHG

论文截图
上一条:DP法工期优化
下一条:Java性能优化
版权:如无特殊注明,文章转载自网络,侵权请联系cnmhg168#163.com删除!文件均为网友上传,仅供研究和学习使用,务必24小时内删除。