LOADING

加载过慢请开启缓存,浏览器默认开启

interview scalable I/O event

2023/3/21 interview io

io多路复用

设计高性能的网络服务器,一般多线程,但是cpu的上下文切换效率很低

那么如何用单线程来弄呢?

Select

准备文件描述符,以及最大的文件描述符

写一个while(true)

select(max+1,&rset,NULL,NULL,NULL)

&rset是一个bitmap,表征哪一个是被监听的,默认1024为

流程

1.对应rset,select,把rset交给内核,全量拷贝到内核

2.是一个阻塞函数,没有到来的时候会一直阻塞在select

3.有数据来了,将FD置位,然后select返回

4.遍历FD,判断哪些被置位,然后进行处理

特点:1.交给内核决定是否有数据(提高的效率)

2.可能是多个有数据,所以需要遍历fd集合

缺点:

1.bitmap默认大小1024

2.fdset会将其置位,然后每次都需要重新赋值,fdset不可重用

3.拷贝过程开销比较大(从用户态到内核态)

4.Select返回的时候,我们还需要遍历一遍

poll

struct pollfd{
    int fd;
    short events;
    short revents;//对events的回馈
}
poll(pollfds,5,50000)

流程

1.工作原理和select类似

2.没有采用bitmap,采用了pollfd

3.同样为阻塞函数

4.内核置位是置的revents这个字段,然后返回

5.然后进行判断,判断revents是否有值,有的话我们把它置位为0

改善:

可以解决select的1和2 缺点

epoll

流程:

1.调用epoll_create创建一个epfd,创建完了是一个白板

2.调用epoll_ctl,在epfd上添加文件描述符+events的结构体(events和fd两个字段)

3.执行nfds=epoll_wait,epfd在用户态内核态共享的,所以不需要数据拷贝,解决了缺点3

4.wait也是阻塞函数,但如果有数据的话,先置位(重排,有数据的放在最前面),然后再返回,这个是有返回值的,返回有多少个有触发事件

5.现在只需要遍历前nfds个元素就ok了