服务器的调度策略
服务器的调度策略
不管是基于UDP实现的服务器或者是基于TCP实现的服务器,都需要处理多个客户端请求。
基于UDP实现
由于UDP协议不需要连接,因此服务端只需要一个套接字便可与任意个客户端通信,但默认的套接字是阻塞型的,这意味着当客户端没有发来消息的时候,服务端如果调用 recvfrom() 将会进入不限期阻塞而无法做别的事情。
基于TCP实现
对于TCP服务器而言,每当有一个远端的客户端发起连接成功后,服务端这边都会新增一个已连接套接字与之匹对,那么随着客户端连接的越来越多,服务端要处理的套接字也随之增多,如何同时妥善处理这些套接字成为必须解决的问题。
这就涉及到服务器要采用何种策略对客户端进行调度,服务器的调度策略也被称为服务器IO模型,指的是当一个服务端网络程序需要同时处理多个套接字时,采取什么方案去妥善处理它们。
(1) 非阻塞轮询
一种方案就是将所有的套接字都设置为非阻塞模式,这样就不用担心客户端不发出数据导致服务器端卡死的问题,但是非阻塞套接字也无法妥善地告知服务器数据何时到达,所以服务器需要不断地尝试读取客户端数据,这就是采用轮询方式实现。
由于非阻塞模式属于套接字的属性,而套接字在Linux系统属于文件,所以通过Linux提供了fcntl()函数可以设置或者获取套接字文件的属性。
(2) 多任务并发
多任务并发模型就是利用多进程或者多线程来达到同时处理多个套接字的目的。一般而言,进程用于具有较完整逻辑块的整合。如果只是处理网络套接字的数据,那么一般使用多线程。
对于UDP而言,由于不存在连接的问题,因此服务端一个UDP套接字可以接收任意的客户端发来的数据,可直接将该套接字交由一条专用于收发数据的线程管理即可。对于TCP而言,首先创建一条专门的线程处理监听套接字,用于随时监听和接受客户端的连接请求。另外由于每当有一个客户端连接成功,服务端都会产生一个新的连接套接字来与之通信,那么就应该每产生一个套接字就分配一条线程与之对应,便可形成多任务并发的服务器IO模型。
(3) 异步信号
指的是用信号来驱使服务器妥善处理多个远端套接字,每当远端有数据到达,那么就在本端触发信号,然后利用信号的异步特性来处理这些远端信息。 SIGIO信号 默认会杀死目标进程,因此必须要设定其响应函数。另外,SIGIO信号由内核针对套接字产生,而内核套接字可以在多个应用层程序中有效(例如父进程将套接字遗传给各个子进程),因此必须指定该信号的宿主。
默认情况下,套接字收到数据时不会触发 SIGIO信号,所以必须将套接字设定为异步工作模式,它才会触发该信号。
由于不管套接字收到何种数据,内核都会触发 SIGIO信号,但是这种方式却不适用于 TCP 协议。
因此在 TCP 中,当客户端发来连接请求、普通数据、数据回执,甚至是断开请求、断开请求的回执等等情况,都触发一样的信号,这就使得服务端光凭这一个信号无法知道下一步要做什么,因此信号驱动的服务器模型,一般只适用于UDP协议。
(4) 多路复用
多路复用指的是通过某个特定的接口来同时监听多路阻塞IO,这就达到既无需多进程多线程,又可以同时处理多个阻塞套接字的目的。
Linux系统中提供了两个函数select()或poll()实现同时监控多个套接字,当发现一个或多个套接字的某种状态就绪(读状态、写状态)时,再调用相应的函数去处理的过程。
三个套接字集合分别关注三个不同的就绪状态,如果需要同时监控某个套接字sockfd的不同就绪状态,则需要将此套接字放入相应的套接字集合中。
select和poll的区别
-
文件描述符数量限制:
- select:基于固定大小的
fd_set结构,默认最大支持1024(32位系统)或2048(64位系统)个文件描述符,修改需要重新编译内核。12 - poll:使用动态数组(链表)存储文件描述符,理论上无数量限制。23
- select:基于固定大小的
-
数据结构与调用方式:
- select:每次调用需重新传递完整的
fd_set集合,且返回后需遍历所有文件描述符以确定就绪的fd。1 - poll:通过
pollfd结构体数组传递文件描述符,返回后仍需遍历整个数组,但支持更灵活的事件类型定义。2
- select:每次调用需重新传递完整的
-
性能差异:
-
两者时间复杂度均为𝑂(𝑛)*O*(*n*)
,但在高并发场景下:
- select的线性扫描效率受限于FD_SETSIZE,文件描述符越多性能下降越明显。14
- poll因无数量限制,在管理大量fd时表现稍优于select,但内核仍需遍历所有注册的fd。25
-
其他关键点
- 事件通知机制:两者均采用主动轮询模式,内核每次调用时遍历所有fd检查状态,导致处理效率随fd数量增长而降低。
- 跨平台支持:select几乎在所有操作系统上可用,而poll的可移植性也较强(但不如select普遍)。
当需要深入理解 I/O多路复用 机制或实现高并发网络编程时,可进一步对比 epoll(Linux特有的事件驱动模型)与其他复用技术的差异。12

浙公网安备 33010602011771号