上海网站建设找缘魁,形象设计公司网站建设方案书,鹤岗哈尔滨网站建设,企业规划设计1.前景回顾 无论是阻塞IO还是非阻塞IO#xff0c;用户应用在一阶段都需要调用recvfrom来获取数据#xff0c;差别在于无数据时的处理方案#xff1a; 如果调用recvfrom时#xff0c;恰好内核没有数据#xff0c;那么阻塞IO会使用户进程阻塞#xff0c;非阻塞IO使CPU进行空…1.前景回顾 无论是阻塞IO还是非阻塞IO用户应用在一阶段都需要调用recvfrom来获取数据差别在于无数据时的处理方案 如果调用recvfrom时恰好内核没有数据那么阻塞IO会使用户进程阻塞非阻塞IO使CPU进行空转都不能充分发挥CPU的作用。 如果调用recvfrom时恰好内核有数据则将内核数据读取到用户区处理即可。 而且在多个读取请求单线程处理的情况下只能依次处理一个个请求一旦正在处理的请求的数据没有准备好那么全体阻塞性能很差。 可以利用多线程来改进但也要考虑上下文切换的时间成本。能不能利用一个线程同时监听这多个读请求一旦哪个请求所需要的数据在内核中准备就绪了我们就去读取数据。 那么用户进程如何知道内核中的数据是否准备好了呢
2.FD(文件描述符) 文件描述符简称FD是一个从0开始递增的无符号整数用来关联Linux中的一个文件也包括Socket。IO多路复用是利用一个线程来同时监听多个FD并在某个FD可读、可写时得到通知从而避免无效的等待充分利用CPU资源。
3.IO多路复用概述 监听FD的方式又有多种实现监听都是在内核实现的常见的有select、poll和epoll模式。
它们之间的差异在于 select和poll只会通知用户进程有几个FD就绪但不确定具体是哪个FD还是需要用户进程逐个遍历FD来确认。 epoll则会在通知用户进程FD就绪的同时把已经就绪的FD写入用户空间。
4.IO多路复用——select select是Linux中最早的I/O多路复用实现方案采用数组实现 4.1select方案的缺点 用户进程无法得知是哪个fd就绪需要遍历整个fd_set。 fd_set监听的fd数量不超过1024。 需要来回将整个fd_set在用户和内核之间互相拷贝。
5.IO多路复用——poll poll模式对select模式做了简单的改进但性能提升不明显也是只会通知用户进程有几个fd准备就绪了。区别就是poll模式在内核中采用链表存储理论上无上限但是监听的FD越多每次遍历耗时也会越长性能反倒会下降。
6.IO多路复用——epoll epoll模式中内核采用的是call back事件回调利用红黑树保存要监听的FD而且每个FD只需要初始时添加一次到红黑树等到红黑树中的FD就绪了会自动触发事件把对应的FD加入到一个就绪列表(list_head)中当用户进程要检查内核就绪列表时(调用epoll_wait)如果列表不为空则返回已就绪的FD的数量并把链表中的值拷贝到用户空间的events数组中用户空间根据数组中的值就能直接定位可以读取的FD然后去读取数据即可。 7.IO多路复用——事件通知机制 对于用户进程来说我们调用epoll_wait函数查看就绪列表就能得到fd的通知。其事件通知的模式有两种LT和ET。一个例子 LT当就绪队列中有可读的FD时调一次通知一次这样会重复通知多次直至数据全部读取完成。(默认)
ET当就绪队列中有可读的FD时只会通知一次然后直接删除不管用户是否一次能够读完。 根据上面的分析我们发现那肯定是LT好但是LT会存在惊群问题比如我们有多个进程同时在关心这一个socket的读取数据其实实际读取操作一两个进程就能完成但是你每次一调用epoll_wait函数都会惊动所有进程去读所以就没有必要。
8.IO多路复用——Web服务流程