22 | 非阻塞I/O:提升性能的加速器
该思维导图由 AI 生成,仅供参考
阻塞 VS 非阻塞
- 深入了解
- 翻译
- 解释
- 总结
非阻塞I/O技术在网络编程中具有重要应用价值。相较于阻塞I/O,非阻塞I/O能够提升性能,并且在应用程序调用完成后立即返回,不会挂起应用程序,从而提高CPU利用率。结合I/O多路复用技术,非阻塞I/O成为高性能网络编程中常见的技术。在非阻塞I/O模式下,需要小心处理读操作立即返回的错误信息,以及尽可能拷贝数据到发送缓冲区中的写操作。此外,将监听套接字设置为非阻塞可以避免极端情况下的阻塞问题。非阻塞TCP套接字上调用connect函数会立即返回连接状态,可以通过I/O多路复用进行检测。文章中提供了一个非阻塞I/O搭配select多路复用的例子,展示了非阻塞I/O的实际应用。总之,非阻塞I/O技术在网络编程中具有重要意义,能够提升性能,值得开发者深入学习和应用。
《网络编程实战》,新⼈⾸单¥59
全部留言(67)
- 最新
- 精选
- HerofH老师您好!我看到您这在应用层设计了一个读写缓冲区,我之前看了muduo和libevent,也是设计了这样的缓冲区,并且muduo作者陈硕也提到非阻塞IO必须要设计一个应用层Buffer,我很疑惑的就是,这样的读写缓冲区的必要性是什么呢? 我大概只能理解到非阻塞IO下使用应用层写缓冲区可以让还未来得及发出的数据先保存在应用层Buffer中,然后等到可写的时候再将数据从应用层Buffer写到fd的发送缓冲区中; 那么如何理解应用层读缓冲区的必要性呢?有数据来,触发可读事件,这个时候直接调用read去读不就可以了吗,为什么一定要先读到读缓冲区呢?根据libevent中,每次读数据时都会尽量多的从fd的接收缓冲区中读取数据到应用层buffer,我的一种想法是,设置读缓冲区的作用,是否是为了减少read的调用次数呢? 还是有其它原因呢?想了解一下老师的看法,谢谢!
作者回复: 读缓冲的作用有很多,你提到了通过设置缓冲区,减少系统调用的次数是一个方面,另外,别忘了读取的数据是需要在应用层进行报文解析的,一个应用层缓冲区显然是比较方便的,否则,需要不断的进行数据的读取,直至解析到完整的报文。我认为,应用层缓冲是"空间换时间"的一个比较好的例子。
2020-01-1438 - TinyCalf我在思考一个问题,select既然已经告诉我们接口可读了,为什么还要用非阻塞IO;我自己的想法是,select其实只通知了有没有内容可读,没有提供有多少数据可读,所以当我们使用阻塞IO循环read时,无法确认下一个read还是不是可读的,因此仍然可能阻塞,而非阻塞IO可以解决这个问题,不知道我想的对不对
作者回复: 我觉得是可以这样理解的。
2020-11-08216 - 衬衫的价格是19美元1.select,poll,epoll是io多路复用技术,是操作系统提供的检测io事件是否就绪的方法,当然我们可以不用操作系统提供的方法而自己去写一个轮训,但是轮训会加重cpu负载。 2.当我们调用fcntl将套接字配置为非阻塞后,在该套接字上后续的accept,read,write操作都将变为非阻塞 3.非阻塞io一般都需要配合io多路复用技术使用
作者回复: 总结到位👍
2020-07-12312 - MoonGod感觉这篇的解释和前面的比起来太不细致了…很多地方都没说明。老师能不能多一些说明啊
作者回复: 我在代码里多加一些注释,可以看最新的代码 https://github.com/froghui/yolanda
2019-09-27412 - 扩散性百万咸面包老师,认真的问你一个问题。 Redis中,网上的介绍是说单线程 + 多路复用 + 非阻塞I/O。为什么不采取C10k问题中的,主从Reactor结构,多个事件分发器来充分利用CPU的多核能力呢?理论上这样更好啊。
作者回复: 很认真的回答你,我觉得你说的 单线程 + 多路复用 + 非阻塞I/O,是和redis的设计有关的,通过这么一个设计,减少了多个线程锁的消耗,我想是redis做了一些取舍的。
2020-06-06210 - fedwing那么非阻塞 I/O 呢?你去了书店,问老板有没你心仪的那本书,老板查了下电脑,告诉你没有,你就悻悻离开了。一周以后,你又来这个书店,再问这个老板,老板一查,有了,于是你买了这本书。注意,这个过程中,你没有被阻塞,而是在不断轮询。但轮询的效率太低了,于是你向老板提议:“老板,到货给我打电话吧,我再来付钱取书。”这就是前面讲到的 I/O 多路复用。 对于这个我有点疑问,select和poll本质上,不都是轮询吗,为什么这里说轮询效率太低,改成select,poll
作者回复: select和poll是"老板"这个内核自己在轮询哦,不是买书人(应用程序)在轮询,"老板"可以有多个方式优化这个过程,比如他记录了一个事件,一旦书定成了,他就发现需要告诉和他有订阅关系的"你"了。想想看,作为应用程序的"你"在这个过程中,是不是可以放开手干点别的事,比如玩个吃鸡游戏的什么。
2020-08-1349 - YUANselect和poll也是轮训吧😄?
作者回复: 我把它归为多路复用。轮询的意思是应用程序自己不断的从应用层发起检测。
2020-10-036 - javaYJL老师,accept()这个函数不是阻塞的吗?
作者回复: accept和阻塞套接字一起使用就是阻塞的,和非阻塞套集字一起使用就是非阻塞的。阻塞和非阻塞是作用到套集字上的。
2019-11-056 - 绿箭侠老师,评论区中 程序水果宝 说select非阻塞,我的理解:select(maxfd + 1, &readset, &writeset, &exset, NULL) 此处因为NULL当然阻塞,不明白为什么说select非阻塞??
作者回复: 非阻塞和阻塞是指I/O,具体作用到的是套接字上,而select这里是I/O多路复用的一种技术,注意到这一行 : make_nonblocking(fd); 实际上是把套接字都改为非阻塞I/O,再通过I/O多路复用来接收套接字上的I/O事件。
2020-02-2835 - 一天到晚游泳的鱼老师,我想请教一个问题就是, 当把一个描述符设置为非阻塞的之后,在该描述符上面的操作就会变成非阻塞的吗? 比如说把连接套接字设置为非阻塞的,send和recv就会变成非阻塞的吗?
作者回复: 你的理解是对的。
2019-10-0525