[GNU/Linux] 常见的IO模型

来源:互联网 发布:机器人算法工程师 编辑:程序博客网 时间:2024/05/17 01:58

常见的IO模型

Unix Network Programming一书中提到了若干个常见的IO模型,大概有:
- 同步阻塞IO(Blocking IO):即传统的IO模型。
- 同步非阻塞IO(Nonblocking IO):此时非阻塞IO的Socket应当被设定为NONBLOCK。
- IO多路复用(IO Multiplexing):也称之为异步阻塞IO,是一种Reactor设计模式。常见的用法有:selectpollepoll
- 异步IO(Asynchronous IO):也称之为异步非阻塞IO,是一种Proactor设计模式。

同步/异步?阻塞/非阻塞?

同步是指用户线程在发起IO请求之后需要等待或者轮询内核IO操作完成之后,才可以继续执行。相对的,异步就是指用户线程在发起IO请求之后依然继续执行,当内核IO操作完成之后通知用户线程或者调用用户线程注册的回调函数。

阻塞则是指IO操作需要彻底完成之后才可以交由用户线程控制,而非阻塞则会在IO操作调用之后立即返回给用户一个状态值,此时IO操作可能并未完成。

理解简单的IO模型

同步阻塞IO

Blocking IO

当我们发起IO请求时,这里以read为例,用户线程就会立即被阻塞,来等待读取的数据到达,如果一直没有数据,那么用户线程就会一直处于阻塞状态,直到数据被复制到用户线程指定的位置为止。

显然的,这种模型存在着一些明显的缺陷,如果数据一直不到达,那么线程将被无休止的阻塞。此时线程将不能进行其他工作,显然是非常低效的。当然,这种模型也存在着一些便利之处,采用这种模型进行IO操作显然在编码上较为简单。

同步非阻塞IO

Nonblocking IO

我们仍以read操作为例,当read没有数据可以读取时,内核将立即提供一个代表读取失败的返回值,这时用户线程可以自由地采取调度策略,是立即尝试再次read或者先处理其他工作等待一段时间之后再次read来获得想要获得的数据。这种模型相比同步阻塞IO相比将更大的自由度给予了线程。但是若线程没有良好的处理各种情况,将造成严重的资源浪费。

IO多路复用

IO Multiplexing

如果我们同时要处理很多个文件的IO操作,显然给每一个文件分配一个线程来处理是相当低效的,虽然线程相比进程而言已经代价已经很小,但如果有成千上万的文件(以套接字为例)需要处理,创建成千上万个线程仍然是难以想象的。

这时我们就可以使用IO多路复用,先监听是否出现了我们需要处理的事件,如果出现了我们就处理,不然的话我们可以选择阻塞掉线程,或者监视是否有新的文件需要处理。

原创粉丝点击