Linux的5种IO模型

版权声明:本文为博主原创文章,转前请跟博主吱一声。 https://blog.csdn.net/Ga4ra/article/details/90183574

1. 阻塞IO模型

这是最简单的 I/O 模型,一般表现为进程或线程等待某个条件,如果条件不满足,则一直等下去。

阻塞式io

直到内核完成数据报复制,应用进程才会退出阻塞状态。

这种模型耗费时间,适合低并发,时效要求不高的情况。

2. 非阻塞IO模型

我们在等待的时候,完全可以做点别的事情,并通过轮询的方式,时不时问一下内核数据准备好没。

非阻塞io

如果某一次轮询得知数据已经准备好了,那就把数据拷贝到用户空间中。

3. 信号驱动IO模型

如果说,内核可以自动地,在复制完数据报后通知咱的应用呢?

信号驱动IO

这就是信号驱动IO。

应用进程向内核指定信号处理函数,收到信号SIGIO后,处理函数自动执行。

那么,如何才能多处理几个io呢?我们可以通过下一种模型,监视多个描述符。

4. IO复用模型

通过IO复用,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

IO复用

select()会监听所有注册好的IO

  • 如果所有被监听的IO需要的数据都没有准备好时,select()调用进程会阻塞;
  • 有描述符就绪则返回就绪的描述符个数;
  • 超时时间内没有描述符就绪返回 0 ;
  • 执行失败返回-1 。
int select(
  int maxfd,
  fd_set *rdset,
  fd_set *wrest,
  fd_set *exset,
  struct timeval *timeout);

注意,IO复用模型并不是非阻塞的,因为没有向内核注册信号处理函数。

5. 异步IO模型

前面的4种模型,都是同步的,因为数据拷贝都是同步进行的,都通过recvfrom操作进行数据拷贝。

对于信号驱动模型,可以认为数据准备阶段是异步的,数据拷贝操作是同步的。

要想异步进行,就必须给内核指定更多任务。

异步IO

用户进程发起aio_read()操作之后,给内核传递描述符、缓冲区指针、缓冲区大小等;内核收到aio_read后,会立刻返回,然后内核开始等待数据准备。

数据准备好以后,直接把数据拷贝到用户空间,省去recvfrom(),然后再通知进程本次IO已经完成。

异步模型显然是最省事的,啥都不用管了。

猜你喜欢

转载自blog.csdn.net/Ga4ra/article/details/90183574