Author:
bugall
Wechat:bugallF
Email:769088641@qq.com
Github: https://github.com/bugallgit
在面试中咱们会碰到这种场景:
面试官:能解释下什么是同步,异步么?程序员
程序员:假如咱们执行A,B两个IO操做的时候,若是必须等待A完成后才能执行B那么这个就是github
同步的,若是A,B能够同时执行那么就是异步的。面试
面试官:那能解释下什么是阻塞什么是非阻塞么?编程
程序员:若是必须等待A完成后才能执行B那么这个就是阻塞的,若是A,B能够同时执行那么就 是非阻塞的多线程
面试官:那你的意思异步/同步的概念与阻塞非阻塞同样了?并发
程序员:嗄。。。能够这么说吧。我以为能够并发执行
的就是异步非阻塞的。one by one执行 的就是同步阻塞的异步
每一个人看去看同一个问题都会有不一样的理解,缘由就是由于每一个人的看待问题的深度不同,就像上面的对白,程
序员的理解只是停留在应用层面,代码里有多个IO操做,每一个IO操做均可以不用互相等待的“同时”执行。函数
接下来咱们就来探讨下异步/同步与阻塞/非阻塞它们其中的区别。操作系统
阻塞 / 非阻塞描述的是函数, 指访问某个函数时是否会阻塞线程(block),致使线程进入阻塞状态。
同步 / 异步描述的是执行IO操做的主体是谁,同步是由用户态的进程本身去执行IO操做,异步是用户态进程不关心IO细节,由内核态进程去完成IO操做而后通知用户态进程。
好的,如今定义已经描述完了。如今能够区分它们之间的区别了么?(吃瓜群众:这TM的写的是什么?) ,别急,咱们下面举栗说明,包教包会。
通常来讲IO分为两个阶段,第一阶段是等待数据阶段,第二阶段是内核空间的数据拷贝到用户空间,假设一个线程(或是进程)P准备执行一个IO操做的话它会经历如下过程:
第一阶段:
P发出一个IO请求,这时候会有两种状况: 1:马上返回: 非阻塞 2:一直等待,P调用sleep/wait休眠或是挂起,让出CPU给别的线程/进程 阻塞
第二阶段:
这时内核的数据终于准备好了, 那么如今用户进程想要读取内核空间的数据有两种方式: 1: P本身把数据从内核空间拷贝到用户空间 同步 2:P建立一个线程作数据copy的工做 异步
如今应该明白了吧。阻塞/非阻塞是针对IO的第一阶段的描述。异步/同步是针对IO的第二阶段的描述也就是IO的主体。
这里主要比较难理解的就是同步/异步。首先P在发起IO的请求的时候若是P自己还要负责IO请求后的数据copy(内核空间到用户空间)工做。那么咱们就能够说是同步的。
若是P在发起IO操做后数据copy的工做由内核线程/进程或是P本身再建立一个线程/进程去完成,那么咱们就能够称之为异步
同步阻塞IO:
同一个线程在操做IO时一直阻塞,直到读取数据成功,而后线程自己负责把数据从核心空间拷贝到用户空间
同步非阻塞:
同一个线程发起IO后,当即得到返回,后面按期轮询数据读取状况,发现数据读取成功,线程自己负责把数据从核心空间拷贝到用户空间
异步非阻塞:
一个线程发起IO后,当即返回,由另外的线程发现数据读取成功,把数据从核心空间拷贝到用户空间。
非阻塞同步IO因为读写方法非阻塞,而且须要用户本身来进行读写,因此每次调用读写方法实际读写的字节数是不肯定的,因此须要一个Buffer来保存每次读写的字节状态。更重要的是用户不知道何时完成了读写,通常须要用
while循环判断Buffer的状态来跟踪读写。非阻塞异步IO因为是内核线程进行读写,而且在IO完成后会回调用户提供的callback,编程模型就比较简单,用户只须要调用读写,提供回调就能够了,好比 read(filename, callback)select / poll / epoll 从本质上说都是非阻塞同步IO,select会收到IO就绪的状态,而后通知用户去处理
IO,实际的IO操做还须要用户等待内核复制操做。
要理解IO就绪和完成的区别。就绪指的是还须要用户本身去处理,完成指的是内核帮助完成了,用户不用关心IO过
程,只须要提供回调函数。
对多处理器而言--多个程序在同一时刻发生,具备并发的含义,但并发不必定并行,也亦是说并发事件之间不必定要同一时刻发生。
并行:在单处理器中多道程序设计系统中,进程被交替执行,表现出一种并发的外部特种;在多处理器系统中,进
程不只能够交替执行,并且能够重叠执行。在多处理器上的程序才可实现并行处理。计算机操做系统中把并行性和并发性明显区分开,主要是从微观的角度来讲的,具体是指进程的并行性(多处理机的状况下,多个进程同时运行)和并发性(单处理机的状况下,多个进程在同一时间间隔运行的)
对单处理器而言--多个程序在同一时间段发生;
并发中又有:互斥和同步:
互斥:进程间相互排斥使用临界资源;好比写操做; 同步:不是排斥关系而是依赖关系,前一个进程的输出是后一个进程的输入 当第一个进程没有结束时第二个进程必须等待,相互协同完成一些事情; 具备同步关系的一组进程并发时发送的消息称为消息或者事件;
同步和异步:
异步:就是线程B在等待A的结果的时候还能够继续干本身的事儿, 之间经过消息和事件来通知对方,提升了程序运行的效率。 简而言之,就是否是站在那儿傻傻死等;异步和多线程并非一回事, 异步是最终目的,多线程只是实现的一种方法。