I/O类型:
同步和异步:关注的是消息通知的机制
同步:调用发出之后不会立即返回,但是一旦返回,则返回调用的结果。
异步:调用发出之后,被调用方立即返回结果。但是并非返回最终结果;被调用方通过状态,通知机制 等通知调用者,或者通过回调函数来处理结果
阻塞和非阻塞:
关注的是调用者等待被调用者结果时的状态
阻塞:调用结果返回之前,调用者一直被挂起,调用者只有在得到返回结果之后才可以继续工作
非阻塞:调用结果返回之前,不会被挂起,即调用不会阻塞调用者
IO模型(5种):
blocking IO:阻塞IO
nonblocking IO:非阻塞IO
IO multiplexing:复用型IO
signal driven IO:事件驱动IO
asynchronized IO:异步IO
例如一次read操作:用户进程----->系统调用------>数据到内核空间------->数据复制到用户空间。
内核处理数据两个过程 1从磁盘获取数据2把内核空间中的数据复制到用户空间中
从用户发起请求到数据返回之前进程一直被挂起这种就是阻塞型IO。
从用户发起请求,到数据从磁盘到内核中,此过程进程处于盲等待的过程(一直轮询内核查看数据是否准备好了)。一旦数据准备好了,此时 为了保证数据的安全,把数据从内核空间复制到用户空间依旧是阻塞的。这种模型是非阻塞IO
非阻塞IO不一定比阻塞IO好
默认情况下如果用户调用内核服务之后,进程不能发送其他IO请求。此时在内核和用户之间增加一层特殊的系统调用。让用户去请求这个中间层。这样的系统调用select(),和poll()就是这样的中间层。事实上这就是向中间层准册IO的过程。不过注册的IO个数有限一般为1024个。注册IO的过程是异步的。整个过程是阻塞的。第一阶段阻塞在中间层,第二阶段是阻塞在数据从内核到用户空间中。这样做的好处是可以接受多路IO。(中间层代替了进程阻塞)
事件驱动型IO:在发送请求之后,在第一阶段过程在不必盲等待,等数据从磁盘到内核中,内核会通知用户。不过第二阶段依旧是阻塞的。即数据从内核空间中到用户空间的过程中进程是被阻塞的。通知机制:水平触发:多次通知,边缘触发:只通知一次。
异步IO:发送请求之后返回 内核在完成第一阶段和第二阶段后通知用户,直接处理数据就可以了。