- Published on
I/O
- Authors
- Name
- noodles
- 每个人的花期不同,不必在乎别人比你提前拥有
简介
在看深入浅出node.js这本书的过程中,遇到了几个容易迷糊的概念,例如阻塞I/O、非阻塞I/O、同步、异步。下面主要从I/O模型上对上面的概念进行理解.
基本概念
I/O复用指的是内核具有当进程指定的I/O条件就位的时候通知进程的能力.
I/O模型
- 阻塞式I/O 在发生系统调用(I/O)的时候,对应的系统调用直到相应的操作完成或者错误时才返回.(例如在进行网络IO时,需要等待网络数据的就绪完成读取才会完成系统调用的返回)
- 非阻塞式I/O 进程可以把一个套接字设置成非阻塞模式.这样当通过该套接字进行相关I/O操作并且需要进程进行等待的时候(例如通过网络读取数据,但是数据并没有就绪的时候), 内核不能将该进程投入睡眠而是返回一个错误标识(轮询)
- I/O复用模型 通过select或者poll来对多个相关的描述符进行监听(此时进程阻塞在select和 poll的调用上)),当描述符状态就绪的时候,返回可读条件然后在通过系统调用来完成对应的I/O操作
- 信号驱动式I/O模型 通过开启套接字的信号驱动式I/O的功能并且添加相应的信号处理函数,当套接字准备好读取的时候,通过信号通知进程来完成响应的I/O操作.这种模式进程是不被阻塞的
- 异步I/O模型 通告系统调用告知内核相应的操作,然后内核在完成相应的操作后会通知进程.这个过程中进程是不被阻塞的.
同步VS异步
同步,异步的概念区分上在于实际上发生系统I/O的时候,是否会阻塞进程.因此上面的前四种模式都是同步I/O,只有最后一种是异步I/O
select
int select(int maxfdpl, fd_set *readset, fd_set *writeset,fd_set *exceptset, const struct timeeval *timeout) 该函数允许进程指示内核等待多个事件中的任何一个发生,在其实一个或者多个事件发生后或者经历了一定时间后唤起进程.该函数的当有描述符就位的时候返回描述符的数目,超时返回0,若出错返回-1,下面对主要的参数进行分析
- timeout 告知内核等待所指定的描述符中任何一个就绪所花的时间.
- 当该timeout结构的代表的值均为0的时候,表示无需等待直接返回
- 当设定一定时间的时候,表示当select返回的时候,不能超过该时间
- 当设置为空指针的时候,表示select会一直等待直至有响应的描述符就绪
- readset writeset exceptset 表示让内核检测响应的读,写,异常描述符,当有响应的描述符就位时返回.
- maxfdpl 指定待测试的描述符的个数
node如何实现高性能的异步I/O
参考自己之前整理的一篇blognode的异步I/O