当前位置: 首页 > news >正文

为什么IO多路复用需要采用非阻塞式IO

近段时间开始学习《Unix网络编程》,代码实现了一个简单的IO多路复用+阻塞式的服务端,在学习了非阻塞式IO后,有一个疑问,即:

假如调用了select,并且关注了几个描述字,当关注的描述字可读时,select成果返回并告诉我对应套接口已可读,此时采用阻塞式read或非阻塞式read去读套接口有何区别,既然已经告诉套接字可读,调用read怎么还会发生阻塞。即本问题,为什么IO多路复用需要采用非阻塞式IO。

当时理解不深,不知道该问题存在原因,第二天偶然刷知乎,刷到了这个问题。现解释如下:

1、首先看下man select解释:

Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.
当某个socket接收缓冲区有新数据分节到达,然后select报告这个socket描述符可读,但随后,协议栈检查到这个新分节检验和错误,然后丢弃这个分节,这时候调用read则无数据可读,如果socket没有被设置nonblocking,此read将阻塞当前线程。
 
即select可能存在如下问题:当新数据到达描述符,select返回描述符可读,但Linux内核协议栈检查到新数据包的校验和错误,故丢弃该数据,采用阻塞式IO去读该套接口,无数据可读,则当前进程阻塞。
2、第二种解释有:
一种典型场景,惊群现象:当采用多线程方式通过select或epoll监听套接字,当新连接到达,则所有监听套接字的线程会通过select被唤醒,但是最终只有一个线程会通过accept与这个新连接建立握手关系,如果采用了阻塞式IO,则其余所有没有接收到accept连接的线程会阻塞。

转载于:https://www.cnblogs.com/scu-cjx/p/7735542.html

相关文章:

  • python内存泄露的诊断(转)
  • expdp和impdp数据泵
  • Mybatis调用存储过程
  • Electron入门介绍
  • win7 下硬盘安装Redhat7
  • EJBCA认证系统结构及相关介绍
  • Hadoop集群(四) Hadoop升级
  • 爬虫模拟登陆 SegmentFault
  • 《OOD启思录》:61条面向对象设计的经验原则
  • 学习C语言指针和链表的体会
  • [bzoj1912]异象石(set)
  • nginx源码分析——配置
  • 模糊查询和聚合函数
  • maxsdk sample中3dsexp.rc点不开并提示specstrings.h中找不到sal.h解法
  • 移动端开发调试工具神器--Weinre使用方法
  • JavaScript 如何正确处理 Unicode 编码问题!
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 〔开发系列〕一次关于小程序开发的深度总结
  • 0基础学习移动端适配
  • 78. Subsets
  • Android 控件背景颜色处理
  • Angular Elements 及其运作原理
  • angular学习第一篇-----环境搭建
  • avalon2.2的VM生成过程
  • Git的一些常用操作
  • go append函数以及写入
  • Java|序列化异常StreamCorruptedException的解决方法
  • JavaScript标准库系列——Math对象和Date对象(二)
  • javascript从右向左截取指定位数字符的3种方法
  • ucore操作系统实验笔记 - 重新理解中断
  • 目录与文件属性:编写ls
  • 如何在 Tornado 中实现 Middleware
  • 少走弯路,给Java 1~5 年程序员的建议
  • 算法-插入排序
  • 我的业余项目总结
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • hi-nginx-1.3.4编译安装
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • #define 用法
  • #Z0458. 树的中心2
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • $.each()与$(selector).each()
  • (+4)2.2UML建模图
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (c语言)strcpy函数用法
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (论文阅读30/100)Convolutional Pose Machines
  • (转)关于多人操作数据的处理策略
  • (转)详解PHP处理密码的几种方式
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core 依赖注入的基本用发
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .net6Api后台+uniapp导出Excel
  • .Net中间语言BeforeFieldInit