同步\异步\阻塞\非阻塞 以及 五种基本I/O模型

同步\异步\阻塞\非阻塞都是针对I/O操作的概念(线程和进程的同步和这里的同步只是叫法一样,实际是不同的概念),至于为什么,后面说到I/O操作的时候会讲。

一、同步\异步\阻塞\非阻塞的概念

首先说一下I/O操作。
一般说的I/O操作是指从磁盘读写数据或者网络传输数据等。应用程序是不能直接进行I/O操作的,必须要通过操作系统来进行。
因为电脑的所有资源都是由操作系统来管理的,为了安全起见,操作系统是默认不信任应用程序的,所以应用程序无法直接访问这些资源,必须通过系统调用通知操作系统来执行相关的操作。
(这里多嘴写一句,我这里用的是操作系统,很多文章里用的是内核,其实是指的是一个东西。最开始的时候,操作系统的作用就是管理计算机的资源,后来随着发展,功能不断增多, 操作系统越来越庞大,就把操作系统和硬件直接相关的、最核心的部分称为内核。内核其实就是计算机科学意义上的操作系统。用内核的好处是可以和内核空间\用户空间,内核态\用户态对应起来,但是新手学习的时候可能会对内核有点困惑。)
另外,I/O操作的速度远远慢于CPU的运行速度,例如从磁盘读写文件等,其中涉及到磁盘的机械运动,每一次读写花费的时候都是毫秒级别的。

总结一下:
1、I/O操作是操作系统来执行的;2、I/O操作的速度很慢。

所以就有了同步\异步\阻塞\非阻塞来描述I/O操作时应用程序的状态。对吧,进行I/O操作的时候,应用程序就闲下来了,而且这段空闲还很漫长,在这段空闲时间应用程序可以同步,可以异步,可以阻塞,可以非阻塞。关于具体的解释,网上有很多生动的比喻,这里就不多加解释了,仅写下概念。

同步:是指在发起I/O请求后,应用程序等到I/O操作的结果才能继续执行下去;
异步:是指在发起I/O请求后,应用程序就可以去执行其他任务,不需要等待I/O操作的结果;
阻塞:是指在拿到I/O操作结果的过程中进程是处于挂起状态;
非阻塞:是指在拿到I/O操作结果的过程中进程是处于运行状态;

二、五种基本I/O模型

因为I/O操作是内核来执行的,我们可以把I/O操作粗略地分为两部分:1、内核将数据准备好;2、将数据从内核空间拷贝到用户空间;
在此基础上,再来讨论I/O模型。

在Unix/Linux下有五种基本的I/O模型:
1、阻塞I/O模型;
2、非阻塞I/O模型;
3、I/O多路复用模型;
4、信号驱动I/OI/O模型;
5、异步I/O模型;

阻塞I/O模型

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

当设置一个套接口为非阻塞的方式时,即通知内核:当请求的I/O操作非得让进程睡眠不能完成时,不要让进程睡眠,而应返回一个错误。
当一个应用程序像这样对一个非阻塞描述符调用recvfrom时,我们称此过程为轮询。当系统调用没有期待时操作发生的时候,内核立即返回一个错误。应用程序不断地查询内核,看看某操作是否准备好,这样子对CPU时间是极大的浪费。当操作准备好也就是数据报准备好的时候,将数据报拷贝到应用缓冲区这一段时间依旧是阻塞的。
在这里插入图片描述

I/O复用模型

应用程序通过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的完成事件。
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值