基于.NET的线程池技术及其应用研究
2012-01-29田素贞王应战
田素贞,王应战
(商丘职业技术学院计算机系,河南商丘476000)
1.问题提出
开发数据库软件最频繁的操作是与数据库服务器进行交互。对于少量的数据,我们可以利用单线程顺序执行,但是对于大批量的数据,单线程顺序与多个数据库进行交互,将无法及时响应用户操作,用户体验非常不好。
在制造业中,工厂对于一种产品至少有几十万条数据,而且工厂会不断生产出新的产品,这样会增加大量的数据。如果把所有的数据都放在一个数据库中,必将会增加数据库服务器的负担。为了今后软件的升级及可维护性,可以将不同产品的数据放在不同主机上。那么,当用户发出请求时,如何从分布在不同主机上的数据库快速获得结果,得到快速的响应?
本文在实际应用中,利用.NET平台,通过多线程技术,实现同时对多个数据库进行交互,提高数据库访问效率,优化用户交互,取得了较好的效果。
2.基本概念简介
2.1.多线程技术简介
首先介绍进程及线程。
进程是具有一定功能的程序,是关于一个数据集合的一次执行过程,进程包括运行中的程序和程序所使用到的内存和系统资源。[1]
线程(Thread)是系统可调度的基本单位,是一组指令的集合,它可以在程序里独立执行,线程是轻量级的进程,通常由操作系统负责多个线程的调度和执行。
一个进程可以包含多个线程,线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,所以它们可以同时执行进程地址空间中的程序代码。[2]操作系统为每个独立的线程安排一些CPU时间,以轮转方式向线程提供时间片,这样,虽然实际上在同一时间只有一个线程在运行,但是由于时间片很小,从而使得每个线程看起来好像都在同时运行一样。
多线程程序设计,就是使单个程序包含多个线程,并且使得多个线程能够并发执行,完成多项任务,以提高系统的效率。[3]当多线程程序执行时,该程序对应的进程中有多个控制流同时运行。与并发多进程程序设计不同的是,多线程程序设计是在一个进程中包含并发执行的多个控制流,并不是把多个控制流一一分散在多个进程中。
多个线程共享同一个进程的地址空间,使得线程创建,线程之间的切换及通信的开销大大降低,可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力,但是如果使用不当,会增加对单个任务的处理时间。[4]
线程池是后台执行多任务线程的集合,它为每一个传入的请求分配一个线程,不占用主线程,也不延迟后续请求处理,从而实现异步处理请求。当所有线程都繁忙时,将额外的任务放在任务队列中,当有空闲线程时执行。当池中的某个线程完成任务后,它将返回到等待线程队列中,等待再次被使用,这种重用可以不需要为每个请求创建和销毁线程,从而减少系统开销。[5]
2.2..NET 框架对多线程的支持
.NET框架为每一个进程提供了一个线程池,使应用程序能够根据需要来有效地利用多个线程。[6]一个线程监视排到线程池的若干个等待操作的状态。当一个等待操作完成时,线程池中的一个辅助线程就会执行对应的回调函数。线程池中的线程由系统进行管理。.NET框架的重要组成部分CLR(Common Language Runtime,通用语言运行时间)内置支持多线程应用,可以通过System Threading命名空间提供支持多线程编程的类和接口。
System Threading ThreadPool类实现了线程池,由于每个进程只有一个线程池,不能创建新的,这个类中所有成员都是静态的,没有公开的构造函数。这样可以把所有的异步编程技术都集中到同个池中。[7]线程池中的线程数目仅受可用内存的限制。但是,线程池将对允许在进程中同时处于活动状态的线程数目强制实施限制(这取决于CPU的数目和其他因素)。默认情况下,每个系统处理器最多可以运行25个线程池线程。即使是在所有线程都处于空闲状态时,线程池也会维持最小的可用线程数,以便队列任务可以立即启动。将终止超过此最小数目的空闲线程,以节省系统资源。一般情况下,每个处理器要维持一个空闲线程。[8]
线程池的执行原理如图1。启动进程,此时线程池并没有创建。将回调方法排入队列(比如调用Thread Pool Queue User Work Item方法)时创建线程池,一个线程监视所有已排队到线程池中的任务,将所有要执行的任务插入到任务队列中,如果有空闲线程就调用执行,否则,就将额外任务插入到任务队列,等待有空闲线程时调用执行。如图3所示。
3.基于多线程的多数据库访问方法
在制造业中,每一类产品都会有很多的数据,并且数据随着时间及产品种类的增多而激增。把所有数据仅仅放在一个数据库中,这对数据库服务器本身的性能提出很高的要求。与数据库交互可能会成为提高软件性能的瓶颈。面对大量的数据,可以把它们按照产品种类分别存储在不同的机器上,这样可以降低对数据库服务器性能的要求,也为今后难以预料的数据剧增提供方便。但是,如何及时地从分布在不同机器上的数据库中取出数据,获得良好的用户交互成为软件开发人员普遍关注的问题。
3.1.串行访问方法
按照传统的编程方法,为了使客户端的请求得到满足,服务器端应用系统必须依次访问多个数据库,如图1所求。对于拥有大批量数据的制造工业,这样访问数据库会花费大量的时间,用户将会等待相当长的时间,这样用户体验非常不好。
图3 多线程并发访问数据库示意图
3.2.基于多线程的并行访问方法
如果采用多线程程序设计,程序性能会有很大的提高。如图2所示,客户端发出请求,比如向数据库中插入数据,服务器收到请求后,启动进程,创建线程池,将每个任务插入到任务中,并分配线程池线程,每个线程池线程可以同时访问数据库。与多个数据库同时交互,并将交互成功的消息返回客户端。程序把占据长时间的数据库交互放到后台去处理,充分利用CPU资源,有效缩短用户等待时间。
3.3.实例验证分析
配置所有测试都是在处理器为奔腾®D 2.6 GHz、内存为1 GB的计算机上进行的,数据库为Oracle 9i。操作系统为Microsoft Windows XP Professional SP2*,所有代码都是在Microsoft Visual Studio.NET 2005*环境下开发。本试验具体内容是向三个数据库中分别插入1000条数据。三个数据库分别放在不同的机器上。
由表1可以明显看出,利用多线程并行执行多任务,效率要比串行执行高。
表1 实验结果
4.结束语
基于.NET平台,利用多线程技术,与分布在不同机器上的数据库同时交互,通过测试,发现多线程技术可以显著提高服务器程序性能,提高系统性能。
[1]Jim Beveridge,Robert Wiener.Win32 多线程程序设计[M].侯捷,译.武汉:华中科技大学出版社,2002.
[2]欧广宇,邓桂英.多线程技术基于 VB.NET的实现[J].微机发展,2004(11):50-53.
[3]杨沙洲,杨学军.多处理机系统线程环境[J].计算机工程与科学,2005(5):94-96.
[4]胡燕翔,孟晗.多进程下子程序综合方法研究[J].计算机工程,2006(15):49-51.
[5]赵海,李志蜀,韩学为,等.线程池的优化设计[J].四川大学学报:自然科学版,2005(1):68-72.
[6]王金保,李伟.用VB.Net创建多线程及同步的几个问题[J].抚顺石油学院学报,2003(3):65 -68.
[7]李双权.一种Java多线程可达性测试框架系统的研究和实现[D].暨南大学,2003.
[8]周炎涛.Windows中的多线程编程技术和实现[J].计算技术与自动化,2002(3):112-119.