IO复用模型之select

clipboard

简单的话,如果一个CPU有三核(相当于三个CPU),一个核调度一个进程或一个线程,当一个进程有三个线程时,三个核各自独立调三个线程,此时不用进行切换调度。但实际上调度的过程是很复杂的,要保存现场又要恢复现场,一个进程一般超过远大于三个线程,而且系统是有多个进程被调度的。所以进程和线程越多则花费在调度的时间消耗就越大。

如果为了减少调度,只用一个进程的话,当有多个套接字时,每次read阻塞读取套接字内容,阻塞的时候进程就无法去处理其他套接字,也是浪费资源。

综上,使用事件驱动模型。

多个套接字放在一起叫反应堆,也可以叫IO复用

IO复用模型在单核CPU,避免了CPU调度,避免了CPU忙于做无用功(比如一个不断执行等待鼠标动作的进程)。

在三核(多核)CPU里,尽量用三个IO复用模型的进程,因为只用一个核就同一时刻只能调度一个进程,尽量充分使用CPU资源。

fd_set 文件描述符集合,最大支持1024个

一个反应堆用一个文件描述符集合表示。

select函数监听fd_set文件描述符集合(反应堆)的文件描述符。

select监听三种反应堆:读反应堆、写反应堆、异常反应堆。

一种反应堆有两个文件描述符集合,一个是传入反应堆,一个是返回结果反应堆。比如读反应堆,如果传入反应堆某一个位置1,则表示该位对应的文件描述符对应的文件可以读了,读完后把结果反应堆对应的位置1表示读完了。处理返回结果的过程叫解复用。

其他普通的文件描述符,比如管道文件也可以监听。

clipboard

readfds:监控有读数据到达文件描述符集合,传入传出参数

writefds:监控写数据到达文件描述符集合,传入传出参数

exceptfds:监控异常发生达文件描述符集合,如带外数据到达异常,传入传出参数

用select监听套接字读操作的时候,select的第二参数readfds是传入传出参数,传入的是想要监听的套接字文件描述符,返回(传出)的当前可读的套接字文件描述符并覆盖在第二参数。

select的第三参数writefds、第四参数exceptfds也是类似。

clipboard

i 下标值

maxi 最大下标值

maxfd 监听文件描述符(套接字)的最大值

nready 当前有多少文件描述符可读

FD_SETSIZE 宏,表示一个文件描述符集合的最大值,一般是1024

rset 读集合(传入传出select第二参数的文件描述符集合)

allset 备份读集合

client数组下标为-1,表示数组元素是无效的。

当client的数组有效时,数组元素不可以初始化为0,因为0是标准输入文件描述符,这里初始化为-1。

clipboard

clipboard

clipboard

猜你喜欢

转载自www.cnblogs.com/xiaozhihong/p/9750843.html