套接字知识整理008-阻塞和非阻塞IO,多路复用,异步IO之间的区别,以及不同函数之间的应用 发布人: sanye 时间: 2021-02-24 分类: 网络SOCKET编程 ## 前言 阻塞和非阻塞IO,多路复用,异步IO之间的区别,以及不同函数之间的应用 ## 概念模型区别和示例 || 阻塞 | 非阻塞 |多路复用|异步IO| |:-------------| :------------- | :------------- |:------------- |:------------- | |概念| 程序调用阻塞 `I/O `完成某个操作时,应用程序会被挂起,等待内核完成操作,感觉上应用程序像是被“阻塞”了一样。 | 当应用程序调用非阻塞 `I/O` 完成某个操作时,内核立即返回,不会把 `CPU` 时间切换给其他进程,应用程序在返回后,可以得到足够的 `CPU` 时间继续完成其他事情。 |示例|你去了书店,告诉老板(内核)你想要某本书,然后你就一直在那里等着,直到书店老板翻箱倒柜找到你想要的书,有可能还要帮你联系全城其它分店。注意,这个过程中你一直滞留在书店等待老板的回复,好像在书店老板这里"阻塞"住了。| 你去了书店,问老板有没你心仪的那本书,老板查了下电脑,告诉你没有,你就悻悻离开了。一周以后,你又来这个书店,再问这个老板,老板一查,有了,于是你买了这本书。注意,这个过程中,你没有被阻塞,而是在不断轮询 |老板,到货给我打电话吧,我再来付钱取书。”|你连去书店取书也想省了,得了,让老板代劳吧,你留下地址,付了书费,让老板到货时寄给你,你直接在家里拿到就可以看了。这就是异步 I/O。| ## 写操作 非阻塞IO 和 阻塞IO 处理方式 | 非阻塞 | 阻塞 | | :------------- | :------------- | | 拷贝→返回→再拷贝→再返回。 |拷贝→直到所有数据拷贝至发送缓冲区完成→返回。 | ## 读写在阻塞模式和非阻塞的不同行为特性 | 操作 | 系统内核缓冲区状态 | 阻塞模式 | 非阻塞模式 | | :------------- | :------------- |:------------- |:------------- | | read() | 接收缓冲区有数据 |立即返回|立即返回| | read() | 接收缓冲区没有数据 |一直等数据的到来|立即返回,带有 EWOULDBLOCK 或 EAGAIN 出错信息| |write()|发送缓冲区空闲|全部数据写入发送缓冲区才返回|能写入多少就写入多少,立即返回| |write()|发送缓冲区不空闲|等待发送缓冲区空闲|立即返回,带有 EWOULDBLOCK 或 EAGAIN 出错信息| read 和 write 的结论 | 操作 | 阻塞 |非阻塞| | :------------- | :------------- |:------------- | | read | read 总是在接收缓冲区有数据时就立即返回.不是等到应用程序给定的数据充满才返回。 | |write|write 只有在发送缓冲区足以容纳应用程序的输出字节时才返回;|则是能写入多少就写入多少,并返回实际写入的字节数 |write|特例:对方主动关闭了套接字,这个时候 write 调用会立即返回,并通过返回值告诉应用程序实际写入的字节数,如果再次对这样的套接字进行 write 操作,就会返回失败。失败是通过返回值 -1 来通知到应用程序的| ## 为什么要将监听套接字设置为非阻塞的? > 在监听套接字上有可读事件发生时,并没有马上调用 accept。由于客户端发生了 RST 分节,该连接被接收端内核从自己的已完成队列中删除了,此时再调用 accept,由于没有已完成连接(假设没有其他已完成连接),accept 一直阻塞,更为严重的是,该线程再也没有机会对其他 I/O 事件进行分发,相当于该服务器无法对其他 I/O 进行服务。 ## connect >在非阻塞 TCP 套接字上调用 connect 函数,会立即返回一个 EINPROGRESS 错误。TCP 三次握手会正常进行,应用程序可以继续做其他初始化的事情。当该连接建立成功或者失败时,通过 I/O 多路复用 select、poll 等可以进行连接的状态检测。 ## 总结 > 在非阻塞 I/O 下,使用轮询的方式引起 CPU 占用率高,所以一般将非阻塞 I/O 和 I/O 多路复用技术 select、poll 等搭配使用,在非阻塞 I/O 事件发生时,再调用对应事件的处理函数。这种方式,极大地提高了程序的健壮性和稳定性,是 Linux 下高性能网络编程的首选。 标签: 节, 函数, 前言, 操作, 程序, 网络, 连接, 队列, 阻塞, select, poll, 事件, 缓冲区, 返回, write, 调用 本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。 取消回复 添加新评论 阁下尊名? 📮邮箱(选填) 博客/主页(选填) 大侠请赐教 !支持Markdown格式 spam send以上是我的留言/建议,请查收! 上一篇: 套接字知识整理007-poll 函数 -多路复用 下一篇: 套接字知识整理009-epoll 的高性能原理是什么 apps format_list_bulleted publish 目录 标签 前言 系统 函数 代码 文件 核心 功能 内容 命令 事件 对象 组件 设计 程序 类型 业务 版本 变量 行 数据 分类 默认知识库数学知识库常数数学公式/推导数论统计学机器学习Prolog算法理论深度学习增强现实数据分析计算机知识库网络网络SOCKET编程网络安全nginx汇编/二进制架构设计UML图架构心经范式编程函数式Erlang面向对象JavaC++coding技巧存储中间件MySQL mongodb虚拟化技术Docker操作系统/运维RHCA笔记RHCEAnsible小书常用命令windowslinux编译技术编译原理客户端ios大前端TypeScriptnodejsangularng8Vue浏览器API建筑知识库