实现NIO需要的系统调用:

1.select系统调用模型

select系统调用,这个系统调用中会需要参数,nfds文件描述符数量(用来限制遍历的文件数量,加速便遍历的速度),读的文件键描述符集合,写文件描述符的集合,被例外条件监控的文件描述符集合,将来使用的时候需要传入一个bitmap用来监控制定编号的文件描述符;

客户端使用socket想要与服务器进行连接时,首先:服务器知道客户端创建了多少个文件描述符,使用bitmap记录产生的文件描述符,并且利用这个bitmap记录需要被监控的文件描述符。

客户端如果有socket发送时会产生中断信号,但是中断的信号只会发送至系统内核,应用程序(服务器也是一个应用程序所以是一个用户态)无法感知哪些文件发生了中断请求,但是我们可以将生成的bitmap复制一份到系统内核,使用DMA监控哪些数据产生了中断(一旦产生了系统中断,那么就表示有一个文件描述符需要进行更改),select系统调用会将此过程中文件描述符发生变化的数量(即产生IO中断请求的数量)返回出去给服务器,服务器依据这个数量,遍历之前记录的文件描述符,一旦遇到的客户端中存在需要处理的数据就对其处理,否则不对其处理;于是实现了一个线程处理多个客户端的连接请求。

select模型的缺陷:

1.由于使用的bitmap记录文件面描述符,所以最大的监控数量为1024个连接;存在数量限制,并且支持的最大数量不算大;

2.bitmap的不可重用,原因前一次的bitmap已经传入内核处理完成了,所以下一次可能状态就不相同了,重新传入;

3.bitmap需要从服务器端复制bitmap给系统内核,以便系统内核返回哪些客户端对应的文件描述符发生了改变;

4.查找的最大时间复杂度是O(n),即使只有一个文件描述符发生了改变,由于每次的遍历是从头开始的,bitmap中可能最高位发生了改变,于是就需要执行n次才能定位到文件的改变,并对其进行处理;