阻塞模式(block):
程序在执行某一项IO的系统调用时,处于阻塞状态,等待IO操作返回后,才能继续向下执行。
例如:
length = recvfrom(data, max_length);
当没有网络数据到来时,程序就会阻塞在这里,直到有数据到来为止。
非阻塞模式(non-block):
程序在执行某一项IO的系统调用时,该系统调用立即返回。
length = recvfrom(data, max_length);
当没有网络数据到来时,recvfrom立即返回,程序判断发现没有数据接收到,可以选择继续循环接收,或者做其他操作。
IO多路复用:
本质是阻塞模式,但是这种模式可以处理多路阻塞IO。调用select() , poll()的时候会阻塞,而不是recvfrom(),等到select监听的某个文件描述符进入就绪状态时,则该路IO操作就可以继续往下执行了。(select,poll等后文介绍)
多路复用的意义在于,单路阻塞会导致程序完全阻塞,而多路的时候,只要有某路就绪,则可以立即服务。在技术上和阻塞模式是没有什么区别的。
信号驱动的IO模式:
程序让内核在文件描述符就绪时,通过信号告知程序,程序通过注册的信号回调函数,对数据进行拷贝(内核到用户态)及处理。
异步模式(asynchronous):
程序在发起一项IO系统调用时,告知系统该调用是异步调用,同时,需要告知系统一个回调函数,IO系统调用完成后(完成数据准备),由系统调用该回调函数。
和信号驱动的IO模式的区别在于,后者的数据拷贝工作占用的是应用程序的时间片,前者则是内核来完成。
程序在告知系统调用为异步调用,并完成该接口调用后,就不用关心该IO操作是否完成,即可继续向下执行程序中的其他逻辑。
几种模式的综合对比:
上述图片来自《linux网络编程》