在unix环境下,有5种IO模型,前4种属于同步IO:
- 阻塞式IO
- 非阻塞式IO
- IO复用(select和poll,还有更好的epoll)
- 信号驱动式IO(SIGIO)
- 异步IO(aio_系列函数)
阻塞式IO
最流行的IO模型,默认情况下,所有套接字都是阻塞的,例如read,write,recvfrom.不再赘述(要注意不等于同步)
非阻塞式IO
进程把一个套接字设置成非阻塞是在通知内核:当所请求的IO操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠,而是返回一个错误.
例如调用recvfrom时,如果内核空间无数据报准备好,则立即返回EWOULDBLOCK错误.如果有的话就会阻塞一直到IO完成.(按理论来说这种也属于同步IO)当一个应用进程对一个非阻塞描述符循环调用recvfrom时,称之为轮询,缺点式耗费cpu.
IO复用模型
调用select,系统阻塞在这个系统调用上,而不是真正的IO系统调用上,例如进程调用select,等待任一套接字变可读,一旦返回说明某个套接字的状态发生了变化,之后继续处理.
信号驱动式
即让内核在描述符就绪时发送信号SIGIO通知进程,可以通过开启套接字的信号驱动式IO功能,通过sigaction系统调用安装一个信号处理函数.
这种优势在于等待数据报到达期间进程不被阻塞.
异步IO模型
告知内核某个操作,并让内核在整个操作完成后再通知进程.
总结:前四种IO的第一步各不相同,但第二部都一样,都会阻塞等待IO完成.但第五种不会阻塞.