博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么IO多路复用需要采用非阻塞式IO
阅读量:6509 次
发布时间:2019-06-24

本文共 1103 字,大约阅读时间需要 3 分钟。

近段时间开始学习《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

你可能感兴趣的文章
Microsoft Team Foundation Server 2010 安装 序列号 注册码(转载)
查看>>
Mongodb 利用mongoshell进行数据类型转换
查看>>
正则表达式 java版
查看>>
Qt5.12.0 交叉编译搭建
查看>>
UCGUI做汉字显示
查看>>
Matches Puzzle Game
查看>>
thinkphp3.2.3 定时任务重新加载, 无法加载新的定时任务的问题
查看>>
MVC基础
查看>>
让代码更容易读
查看>>
WPF and Silverlight 学习笔记(九):WPF布局管理之Canvas、InkCanvas
查看>>
CentOS+LAMP怎么设置文件夹的权限
查看>>
RCC BUCK-BOOST变压器设计
查看>>
一名提高选手的数论之路(二)
查看>>
Bitcoin 的基本原理
查看>>
取某个数字的各个位数字
查看>>
ajax对服务器路径请求
查看>>
软件工程相关问题
查看>>
电商项目系列文档(三):秒杀的设计
查看>>
Erlang垃圾回收机制的二三事
查看>>
Android开源框架Universal-Image-Loader解析(一)
查看>>