五种I/O模型

阻塞和非阻塞

1、阻塞:

         阻塞的系统调用是指,当进行系统调用时,除非出错(被信号打断也视为出错),进程将会一直陷入内核态直到调用完成。

2、非阻塞:

          非阻塞的系统调用是指无论I/O操作成功与否,调用都会立即返回。

3.在Linux环境下,所有的I/O系统调用都是阻塞的,我们可以给socket系统调用的第二个参数传递SOCK_NONBLOCK标志,或者通过fcntl系统调用的F_SETFL,将其设置为非阻塞的。

//将文件描述符设置为非阻塞的
int setnonblocking(int fd)
{
    int old_option = fcntl(fd,F_GETFL);//获得原属性
    int new_option = old_option | O_NONBLOCK;//新加非阻塞属性
    fcntl(fd,F_SETFL,new_option);//设置新属性给文件描述符fd
    return old_option;
}

I/O模型

1、一个输入操作一般有两个不同的阶段:

  •           等待数据准备好
  •           从内核到进程拷贝数据

     对于一个套接口上的输入操作,第一步一般是等到数据到达网络,当分组到达时,它被拷贝到内核中的某个缓冲区,第二步是将数据从内核缓冲区拷贝到应用缓冲区。

2、UNIX下五种I/O模型

  • 阻塞I/O
  • 非阻塞I/O
  • I/O复用(select 和 poll)
  • 信号驱动I/O
  • 异步I/O

阻塞I/O模型

          进程调用recvfrom,从用户态转到内核态,直到数据准备好且拷贝到应用程序缓冲区或者出错(最常见的错误是信号中断)才会返回。我们所说的进程阻塞的整段时间是从调用recvfrom开始到数据拷贝完成这段时间。当进程返回成功时,应用程序就开始处理数据了。

非阻塞I/O模型

          当设置一个套接口为非阻塞的方式时,即通知内核:当请求的I/O操作非得让进程睡眠不能完成时,不要让进程睡眠,而应返回一个错误。      

          当一个应用程序像这样对一个非阻塞描述符调用recvfrom时,我们称此过程为轮询。当系统调用没有期待时操作发生的时候,内核立即返回一个错误。应用程序不断地查询内核,看看某操作是否准备好,这样子对CPU时间是极大的浪费。当操作准备好也就是数据报准备好的时候,将数据报拷贝到应用缓冲区这一段时间依旧是阻塞的。

I/O复用模型

         应用程序通过I/O复用函数向内核注册一组事件,内核通过I/O复用函数把其中就绪的事件通知给应用程序。I/O复用本身阻塞的,他们能提高程序运行的效率的原因在于他们具有同时监听多个I/O事件的能力。

         常用的I/O复用函数是select,poll,调用select或poll,在这个两个系统调用中的某一个上阻塞,而不是而不阻塞于真正的系统调用。

以select为例,我们阻塞于select调用,等待数据报套接口可读。当select返回可读调用时,调用recvfrom将数据拷贝到应用程序缓冲区。

信号驱动I/O模型

          通过系统调用安装信号处理程序,此系统调用立即返回,进程继续工作。当数据报准备好之后,会为该进程生成一个SIGIO信号。随即可以在信号处理函数中调用recvfrom来处理数据,并通知主程序体数据已经准备好被处理了。

          信号驱动I/O模型的优点是当数据报到达时,可以不阻塞,主循环可以继续执行,只是等待信号处理程序的通知,或者数据已准备好被处理,或者数据报已经准备好被读了。

异步I/O模型

          用户可以直接对I/O执行读写操作,这些操作告诉内核用户读写缓冲区的位置,以及I/O操作完成之后内核通知应用程序的方式。异步I/O的读写操作总是立即返回,而不论I/O是否阻塞,因为真正的读写操作已由内核接管。

           下面实例中,假设要求内核在完成操作后生成一个信号,此信号直到数据已拷贝到应用缓冲区才产生,通知用户已经处理完事件。

五种I/O模型的比较:

          阻塞I/O,非阻塞I/O,I/O复用,信号驱动I/O都属于同步I/O,同步I/O模型要求用户代码自动执行I/O操作(将数据从内核缓冲区读入用户缓冲区,或者将数据从用户缓冲区写入内核缓冲区)。可以认为,同步I/O向用户返回的是就绪事件。而异步I/O机制则由内核来执行I/O操作(数据在内核缓冲区和用户缓冲区之间的移动是由内核在“后台”完成的)。可以理解为异步I/O向应用程序通知的是I/O的完成事件。

 

 

 

 

 

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值