什么是客户/服务器程序设计范式?简单点儿说就是在写客户/服务器相关程序时的一些特定的设计方式,将这些设计方式总结起来,形成几种固定的模式,就叫客户/服务器程序设计范式.
这里叫客户/服务器程序设计范式,其实大部分讲的是服务器程序设计范式,而客户程序的编写通常比服务器程序容易一些,因为客户中进程控制要少的多.
尽管如此,我们还是会提及编写客户程序的各种方式.
从总体上来说服务器设计范式分为循环设计和并发设计两种,也就是我们经常说的“迭代服务器”和“并发服务器”.
迭代服务器程序是最简单,也是最容易编写的,但这种类型适用情形极为有限,因为这样的服务器在完成对当前客户的服务之前无法处理已等待服务的新客户.
并发服务器实现起来有很多种方式:
- 为每个客户调用fork派生一个子进程的方式(据说apache1.0就是这么干的);
- 预先派生子进程的方式(apache里的prework模块就采用这种方式);
- 为每个客户请求创建一个线程的方式;
- 预先创建线程的方式;
- 当然还有多进程、多线程混合模型(apache中的worker模块采用这种方式);
- 还有一种比较特殊的方式,就使在单个进程中使用select处理任意多个客户请求等等。。。
而客户程序设计在大多数情况下迭代的方式就能够满足需求,虽然它是以停-等方式运作.
而在一些特殊情况下,还是要有一些变通方式.比如,客户程序阻塞在用户输入其间,对网络连接相关事件是看不到的.此时可以用select使得进程在等待用户输入其间能够得到网络事件通知;也可以用非阻塞I/O来实现。
当然客户程序也可以用fork派生子进程,或者用多线程来实现并发。
在下面我们会对各种服务器设计范式进行测试,并讨论这些范式之间的差异。主要包括以下几种范式:
- 迭代服务器程序《客户/服务器程序设计范式---迭代服务器程序》
- 并发服务器程序,每个客户一个子进程《客户/服务器程序设计范式--并发服务器程序,每个客户一个子进程》
- 预先派生子进程服务器程序,accept无上锁保护《客户/服务器程序设计范式--并发服务器程序,accept无上锁保护》
- 预先派生子进程服务器程序,accept使用文件锁保护《客户/服务器程序设计范式--并发服务器程序,accept使用文件上锁保护》
- 预先派生子进程服务器程序,accept使用线程锁保护《客户/服务器程序设计范式--并发服务器程序,accept使用线程上锁保护》
- 预先派生子进程服务器程序,传递描述字《客户/服务器程序设计范式--并发服务器程序,传递描述符》
- 并发服务器程序,每个客户一个线程
- 预先创建线程服务器程序,每个线程各自accept
- 预先创建线程服务器程序,主线程统一accept
我们将针对每个服务器程序运行同一客户程序的多个实例,以测量服务固定数目请求所需的CPU时间。注意,这里的时间指的是用于进程控制所需的CPU时间,而迭代服务器是我们的基准,因为迭代服务器没有进程控制开销。所以从其他服务器的实际CPU时间中扣除迭代服务器的实际CPU时间就得到相应服务器用于进程控制所需的时间。
接着,我们讨论各种客户设计范式,主要包括以下几种:
- 迭代客户程序
- 调用select用单线程实现并发
- 使用非阻塞I/O实现的客户程序
- fork派生子进程的方式
- 多线程的方式
最后我们会看到,非阻塞I/O尽管是最快的,但其代码比较复杂;使用两个进程/线程的版本相比之下简化的多,而运行速度只是稍逊而已。
reference:
<
>
<<用TCP/IP进行网际互连--客户-服务器编程与应用(linux/posix套接字版)>>
阅读(982) | 评论(0) | 转发(1) |