【IO专题】同步 异步 阻塞 非阻塞概念问题 + 两两组合后的易混淆问题
本问题对应的项目链接:高频题回答模版训练
PS:这部分的话,主要就是要**理解**,千万不能记忆,很多人会把 同步/异步 和阻塞/非阻塞 之间搞混淆。问题的关键,就是要先理解「字面意思」。
1、解释一下 同步 异步 阻塞 非阻塞 的概念?
2、同步/异步 和 阻塞/非阻塞 有什么区别?
3、解释下我们常说的 IO 是指什么?
4、什么是 阻塞IO和非阻塞IO?
5、什么是 同步IO和同步阻塞IO?
6、那你再说一下什么是 异步IO和异步阻塞/非阻塞IO?
共以下 2 个回答
同步也是协同,协同两个事务执行的先后顺序,比如方法里面一行行代码是按顺序执行的,一个事务里按顺序执行一个个方法。所以同步是不能同一个时刻执行多个事务。比如现在有两个方法,第一个方法是从数据库读数据并写入缓存,第二个方法是从缓存中读数据,所以第一个方法肯定是在第二个方法前面执行,第一个方法和第二个方法不可以同时执行,第二个方法必须等到第一个方法执行完成后才可以执行。而异步是指同一个时刻可以执行多个事务。比如现在有两个方法,方法A执行向表A写数据,方法B执行向表B写数据。方法B可以在方法A之前执行,也可以在方法A开始时同时执行,也可以在方法A执行过程中开始执行,也可以等待方法A执行完后执行,所以异步不用去协同事务的执行顺序。
当你执行一行代码或者调用一个方法时,如果需要等待结果返回,才可以执行其它操作,是阻塞。不用等待结果返回就可以执行下一步操作就是非阻塞。
同步/异步 是根据是否需要协同多个事务的执行顺序来区分。阻塞/非阻塞 是根据执行代码后是否需要等待返回结果来区分。
IO指的是读写数据的过程,也就是数据在用户空间和内核空间之间的拷贝过程,包括等待数据的过程,也就是等待数据从外接存储设备或者网络到内核空间的过程。
阻塞IO就是当用户线程调用IO函数时,用户线程需要等待IO的结果返回,一直等待在内核空间和外接存储设备之间的数据拷贝、内核空间和用户空间的数据拷贝这两个过程,这两个过程完成之后用户线程才可以执行其它操作。非阻塞IO就是用户可以不用等待IO函数的返回结果直接去执行其它的操作。
同步IO就是同步阻塞IO,也是阻塞IO。因为对于IO而言,同步和非阻塞是不可能同时存在。同步说明后面的操作需要依赖IO的返回数据,非阻塞说明后面的操作不需要依赖IO的返回数据,如果你设计一个同步非阻塞IO函数,后面的操作就可能去操作不存在或者不完整的数据。
异步阻塞IO是用户线程在等待内核空间和外接存储设备之间的数据拷贝时是异步的,可以执行其它操作,但会阻塞在用户空间和内核空间之间的数据拷贝,因为用户线程需要参与,所以异步阻塞的。而异步非阻塞IO是用户线程不参与等待数据和数据拷贝的过程,也不需要等待IO函数的结果,只需要IO函数执行完成后通知它,所以是异步非阻塞IO。
1、解释一下 同步 异步 阻塞 非阻塞 的概念?
同步就是指多个事件不能同时进行,需要按照一定的次序一个一个进行。异步就是指多个事件能够同时进行,互不干扰。
阻塞就是某个事件由于某些原因不能进行,需要停下来等待,但在等待的期间可以干其他事情。非阻塞就是事件的进行畅通无阻,没有阻碍。
2、同步/异步 和 阻塞/非阻塞 有什么区别?
同步/异步关心的是事件之间能不能同时进行,阻塞/非阻塞关心的是当前事件能不能够继续进行。
也可以把它们两两组合,以线程为例子:
同步阻塞,相当与同一时刻只能运行一个线程,并且此时还在等待。
同步非阻塞,相当与一个线程在正常运行。
异步阻塞,相当与同一时刻可以运行多个线程,但此时某些线程在等待。
异步非阻塞,相等于多个线程都在同时正常运行。
3、解释下我们常说的 IO 是指什么?
IO 是读/写数据的过程,以及等待数据进行读/写的过程。拿网络 IO 来说,等待的过程就是数据从网络到网卡再到内核空间,真正读写的过程是数据从内核空间到用户空间的相互拷贝。
4、什么是 阻塞IO和非阻塞IO?
阻塞IO 是指程序在发出 IO 请求时,如果数据没有准备好或无法立即进行读取或写入,程序将会被阻塞,也就是暂停执行,直到操作完成或者有数据可用,才能进行下一步操作。
非阻塞 IO 则是相反的概念。非阻塞 IO 是指程序发出 IO 请求时,如果数据没有准备好或无法立即进行读取或写入,程序不会被阻塞,而是立即返回,并允许程序去执行其他任务。程序可以定期轮询 IO 操作的状态,来确定何时数据已经准备好,或者可以使用回调函数或事件通知等机制来接收通知。
5、什么是 同步IO和同步阻塞IO?
同步IO 就是同步阻塞 IO,都属于阻塞IO,表示程序发起 IO 请求后,必须拿到 IO 的数据后才能继续执行,并且在等待数据或者拷贝数据的期间,程序都是阻塞状态。
6、那你再说一下什么是 异步IO和异步阻塞/非阻塞IO?
异步IO 就是程序发起 IO 请求后,不用拿到数据就可以继续执行,也就是在等待数据的过程中,程序是可以继续执行的。但根据拷贝数据时程序是否阻塞,又可以分为异步阻塞/非阻塞IO。
也就是说,等待数据过程中,程序继续执行,但拷贝数据时程序阻塞,是异步阻塞IO。等待过程中,程序继续执行,拷贝数据时程序也继续执行,是异步非阻塞IO。