基于Linux的多线程池并发Web服务器设计

2015-01-04 08:51任海兰
电子设计工程 2015年11期
关键词:信号量生产者线程

陈 涛,任海兰

(武汉邮电科学研究院 湖北 武汉 430074)

Web服务器常常需要处理多个并发请求,针对每一个请求,Web服务器会有相应的并发程序来执行相关操作。

这一过程中,使用进程是构造并发程序最简单的方法:为了实现进程间的信息交互,它们必须使用显式的进程间通信((IPC)机制,由于进程控制和IPC的开销很高导致基于进程的设计运行速度往往比较慢[2-4]。

为解决进程间信息共享而造成的高开销问题,本文采用多线程池的并发设计,利用信号量访问共享变量,使用生产者一消费者模型降低线程开销,从而提高系统访问速度和资源利用率。

1 基于多进程Web服务器的不足

目前主流boa服务器主要基于多进程来构造并发程序。首先由父进程去接受客户端的连接请求,然后创建一个新的子进程去为每一个客户端提供服务。这种父子进程会共享文件表,但是不共享用户地址空间。基于这种特性,这类进程中不会存在一个进程覆盖另一个进程的虚拟存储器,但是这也使得进程共享状态信息变得更加困难,因而基于多进程Web服务器引入了IPC机制。

在面对大量并发处理请求时,由于进程机制和IPC机制开销大,会使得服务器延时效果明显。

2 改进服务器的设计要素

2.1 基于线程池的并发设计

线程是程序执行流的最小单元,线程由内核自动调度。一个进程里可以同时运行多个线程,每个线程都有自己的线程上下文,包括一个唯一的栈、栈指针、条件码、程序计数器、整数线程ID、通用目的寄存器,运行在同一个进程里的所有线程共享该进程的整个虚拟地址空间。

同时,线程执行又区别于进程执行,在于:1)较于进程环境,一个线程环境拥有的系统资源极少;2)线程不构成父子层次关系。

在线程池技术中,我们在任务还没有到来之前,创建一定默认数量的线程。这些线程均处于睡眠状态,不消耗CPU,只占用较少的内存空间。当轮询到有请求到来后,线程池将会分配给这次请求一个空闲的线程,进行执行。

当预先创建的线程都已处于运行状态,即并发请求数量多于线程池中最少空闲线程数时,线程池将会自由创建一定数量的新线程,用于处理更多的并发请求。当系统比较闲的时候,线程池就会移除一部分已经停用的线程,以减少系统负荷。

线程池技术由于具有节省系统开销,信息共享容易,完成时间短的优点非常适合处理大数量的并发请求。

2.2 基于信号量机制的资源共享

信号量模型只支持P,V两种操作,且均为原子操作,要么都不执行,要么全部执行[5-6]。

1)P(s):如果 S 为非零,那么 P 操作就将 S 的值减 1,然后返回。如果S为零,那么当前进程(线程)将会被阻塞,直至S值不为0;当S值不为0,被阻塞的进程会重启。重启之后,S的值减1。

2)V(s):对S进行操作,就是将 S的值加 1。 为实现内核同一时刻对共享变量的互斥访问,将信号量(初始值为1)与共享变量联系起来,用P和V操作将相应的临界区保护起来,从而使得在任何时间点上,信号量操作确保对临界区的互斥访问。

调度对共享资源的访问是信号量的另一个重要作用,在某一时刻,程序中某个条件一旦为真,一个线程会通过信号量来告知其他线程允许访问。

2.3 生产者一消费者模型

图1所示的生产者—消费者模型是一个经典的信号量调度同步示例。生产者和消费者线程共享一个有限单元的缓存区。

图1 生产者一消费者模型Fig.1 Producer-consumer model

生产者线程不断地生产新的项目并把它们插入到缓存区中;消费者线程则不断地从缓存区中取出这些项目,然后消费它们。模型中允许有数量不同的生产者和消费者。

在本次设计中,生产者线程,消费者线程均来自于线程池。主程序轮询到请求到来后,线程池会给请求分配一个空闲的线程,进行相关任务的执行。

由于插入和取出两种操作涉及到对缓存区共享变量的更新,所以需要保证它们的互斥访问。除此之外,还需要考虑调度对缓存区的访问,例如,当缓存区为空的时候,消费者将被阻塞,直到不为空的时候被唤醒;同理,当缓存区满的情况下,生产者应该被阻塞,等待有空的位置出现。

3 多线程池并发的Web服务器设计

3.1 设计模型

在Web服务程序中,通常将收到的客户请求分为如下4个部分来进行处理:

1)监听服务端口,与客户端建立连接;

2)解析URL与报头;

3)静态/动态请求处理;

4)消息的应答机制。

本文基于多线程池并发Web服务器设计模型如图2所示。

图2 多线程池并发服务器模型Fig.2 Concurrent multi-threaded server model pool

图2 中每一个数据队列均有对应的线程池对其进行轮询。在每个线程池中,都有一定数量的处于睡眠状态的线程。主程序在监听到请求后,将请求消息放入请求解析数据队列。线程池轮询到有新请求,会给每个消息请求分配一个空闲线程。当有多个并发请求到来时,将会出现报文解析线程组。用户请求信息完成报文解析处理后,将进入事物处理请求队列。请求在事物处理队列和消息回复队列中的处理机制一致。

这样一来,每种任务线程最多只需关心自己的处理程序,与和自己相关的几个消息队列即可。这种方式使服务模块化,易于管理和维护。流水线的工作方式使服务器的多任务处理性能得到进一步优化。

3.2 Web服务器主要处理流程

根据网络应用程序的开发模型和HTTP协议,Web服务器设计实现的主要操作流程及功能如下:

1)主函数处理流程:缓冲I/O初始化->打开监听端口->建立线程组->监听请求连接->将连接放入线程组->从连接组中取出连接->执行指定服务。

2)服务器响应请求流程:读取请求->获取请求方法、URL、和版本->判断请求方法->解析URL->判断访问权限->放入事务请求处理队列。

3)解析 URL流程:根据 CGI判断静态/动态标服务->拷贝URL到FILENAME中->添加默认文件home.html->返回静态/动态标志。

4)为客户端提供静态服务流程:打开指定文件->拷贝到虚拟内存->拷贝虚拟内存至指定账户->关闭描述符、释放虚拟内存。

5)为客户端提供动态服务流程:构造线程来执行CGI程序->通过调用不同的参数,来产生细节不同的动态文档->等待线程执行结束,回收资源。

4 改进Web服务器性能测试

依据上述设计理念,Web服务器在Linux系统下采用C语言编写,用gcc编译实现。

图3给出了访问静态页test.html的效果示意图,图4给出了访问动态页cgi-bin/add的效果示意图。测试证明该Web服务器能实现服务器的基本功能,即在服务器端接收到HTTP请求后,可以予以响应。

图3 静态页面Fig.3 Static pages

图4 动态页面Fig.4 Dynamic pages

Apache中有个名为ab的程序,可以对Apache其它类型的服务器进行网站访问压力测试。本文使用该软件来进行压力测试,两次测试中,均向目标Web服务器累计发出1 000次请求,每次100个请求并发(模拟 100人同时访问),图5为普通嵌入式Boa服务器测试结果截图,图6为改进后Web服务器测试结果截图。

图5 普通web服务器测试结果Fig.5 Results of ordinary web server test

图6 改进后Web服务器测试结果Fig.6 Results of improved web server test

这两份性能测试单有两个重要测试指标:1)每秒钟平均处理的请求数;2)每个线程下的一组请求(100个)平均消耗时间。改进服务器前后数据分别为:7.35/9.19(改进后),13 607.549 ms/10 884.814 ms(改进后)。

通过数据可以看出改进后的Web服务器能有效降低系统开销,大幅度提高Web服务器的系统资源利用率和服务效率。

5 结束语

基于进程或单纯基于线程服务器普遍会存在着利用率不高、资源消耗大等问题。本文设计的基于多线程池并发Web服务器,利用生产者一消费者模型和多线程池高效率实现了资源调度及共享。设计实现的改进Web服务器能实现Web服务器的基本功能,能接受一定规模的并发客户请求并予以响应,具有较高的服务效率。后续还有一些工作需要完善,如进一步完善用户的动态请求处理,加强对请求头信息的分析等。

[1]Randal E Bryant,David O'Hallaron.Computer systems:a programmer's perspec;tive[M].New Jersey:Prentioe Hall Publisher.2003.

[2]张根宝,胡杰.Linux集群环境下监控Web服务器的Shell脚本设计[J].化工自动化及仪表,2010,37(10):99-101.ZHANG Gen-bao,HU Jie.Shell script design of monitoring web server under linux cluster environment[J].Control and Instruments in Chemical Industry,2010,37(10):99-101.

[3]张估,曹奇英.Web服务器负载压力模型及其优化原则[J].计算机应用软件与软件,2010,27(12):139-141.ZHANG Gu,CAO Qi-ying.Load pressure model and optimization principles of web server[J].Computer Applications and Software,2010,27(12):139-141.

[4]胡中栋,曾志勇.基于多路径的DSR路由协议改进[J].江西理工大学学报,2011,32(3):45-48.HU Zhong-dong,ZENG Zhi-yong.Improved DSR-routing protocol based on multipath[J].The Jiangxi University of Science and Technology Journal,2011,32(3):45-48.

[5]Richard Stevens W,Bill Fenner.Unix network programming volume 1:the Sockets networking API,third edition[M].New Jersey:Prentice Hall Publisher,2003.

[6]Tanenbaum A.Modern operating systems,third edition[M].New Jersey:Prentice Hall Pnhlisher,2007.

猜你喜欢
信号量生产者线程
1月巴西生产者价格指数上涨3.92%
基于C#线程实验探究
基于国产化环境的线程池模型研究与实现
2019德国IF设计大奖
Nucleus PLUS操作系统信号量机制的研究与测试
家禽福利的未来:生产者能期待什么?
浅谈linux多线程协作
硬件信号量在多核处理器核间通信中的应用
μC/OS- -III对信号量的改进
Linux操作系统信号量机制的实时化改造