欢迎来到天天文库
浏览记录
ID:13286408
大小:488.50 KB
页数:47页
时间:2018-07-21
《linux环境下的通用线程池设计》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Linux环境下的通用线程池设计1.设计目的Linux一般作为服务器的操作平台,上面跑的都是要求高可靠的7*24小时运行的应用服务系统,其中各种网络应用系统又占了很大比例,比如web服务器、mail邮件服务器等以及其他针对具体业务需要开发的各种网络服务程序。这就对这些应用系统的并发处理能力、稳定性等方面提出了很高的要求。通常情况下,为了满足这些网络应用系统在性能上的要求,会采用以下的一些通用的网络并发处理模式来设计和开发这些服务程序。1,多进程/线程模式这种模式采用的是对一个新来的客户端连接请求,创建一个新的进程/线程去做具体处
2、理该请求的相关任务。当这个任务完成后,该进程/线程退出。在这种模式下,频繁的创建和销毁进程/线程会在时间花消和系统资源上做出牺牲。当这些时间和资源相对于每个进程/线程具体处理的任务来说占的比例很大的时候,这种模式显然是不合适的。比如创建和销毁进程/线程的花的时间为T1,花的资源为S1,进程/线程具体处理任务的时间为T2,需要资源为S2。如果T1/(T1+T2)>10%或者S1/(S1+S2)>10%,那么我们可以认为消耗在创建和销毁进程/线程上的时间或者资源太多。可以看到,如果T2或者S2越大,那么这个比列会越小。所以在这样的模
3、式下,适合处理每次连接需要处理的任务比较复杂、耗时比较长的任务。比如email服务,web服务等。另外一方面,这种一个请求连对应一个进程/线程的方式,在最坏情况下同时处理A个请求需要A个进程/线程同时运行。但是由于硬件和操作系统的原因,系统本身支持的最大进程/线程数是有限的,这也限制了在这种并发处理模式下系统的扩展。当然,这种模式的设计相对简单,而且能够满足大多数情况下的应用。所以是一种非常常见的并发处理服务器设计模式。2,采用多路复用I/O模型(select)多路复用I/O模型是LINUX环境下另外一种经常使用的并发处理模式。
4、利用select(),同时对多个I/O句柄进行堵塞方式的查询。就是说select堵塞在多个I/O句柄上,如果任何一个句柄准备好了数据的读或者写,那么select能够通知相关的事件处理模块去处理具体的任务。在这种模式下,由于是在同一个进程/线程里做相关处理,不用创建新的进程/线程,所以可以避免由于多进程/线程所带来的资源限制,但是同时也带了一个问题,那就是由于是在一个主进程中循环处理各个客户端的请求,如果每个连接要处理的任务消耗时间比较长,或者某一个连接出现异常,长时间不返回,都会影响其他客户的正常请求。所以在这种模式下,一般不适
5、合用来做email,web这样每次请求处理的任务耗时比较长的情况。通常使用的情况是:频繁的数据交互,但是交互的数据量很小。比如聊天系统,比如游戏服务端,短消息网关等。当然,这种并发处理模式相对多进程/线程要复杂一些。以上是两种Linux环境下最基本的网络服务器的设计模型,从这两种变异后的相关模型就更多。比如对于select()多路复用模型同样可以采用综合多线程/进程来做处理。可以看到,针对不同的应用情况和环境,我们可以采用不同的并发处理模型。既然如此,我们设设计一个新的并发处理模型的目的在那里呢?l解决多进程/线程模型的缺点上面
6、我们提到过,在多进程/线程模型下,最坏的情况是A个请求需要A个进程/线程。但是这个数量A本身受操作系统的选择,所以怎样在同样的环境下提供更多的A是我们要解决的问题。另外要解决的一个问题是,避免频繁创建和销毁进程/线程带来的开销。l构建一个通用的体系结构,可以让开发人员很方便地在这个体系上开发一个能够处理大规模的并发出路服务器。高度的抽象,能够让开发人员不关心进程/线程的具体处理/管理逻辑,只关心具体的客户请求任务处理。下面是在该通用线程池体系下主进程的代码:typedefstructtaskNode{//定义你要处理的具体的任务
7、数据结构,比如我要处理网络连接,那么有个intsockfd;//socket连接的句柄}taskNode;voidprintsd(void*task)//这里处理具体的任务{taskNode*node=(taskNode*)task;printf("pthread=%d,sockfd=%d,address=%p",(int)pthread_self(),node->sockfd,task);free(task);//hi,thisfreemustbedo!!!sleep(1);return;}voidmInterface()
8、//这里获得任务,获得任务可以是处理获得的连接句柄或者其他,这里只是{//一个循环,把任务提交给任务队列inti;for(i=0;i<50000;i++){taskNode*task=NULL;task=(taskNode*)malloc(sizeof(task
此文档下载收益归作者所有