在多数的状况下,咱们谈论这几个概念时都是涉及到I/O操做时,当计算机在等待数据从磁盘或者其余存储设备(网络socket)到达用户进程所用空间时所涉及的几个概念。python
咱们认为首先CPU会发出一个I/O操做的通知,而后文件系统或其余会调用相关设备执行这些操做,最后当数据到达用户空间后发出一个中断的完成标志,因而在这个从CPU发出调用到收到完成标志的过程当中就存在一个时间差。如今就有了两个重要的概念:完成标志与时间差。同步与异步是针对获取完成标志而言的,而阻塞与非阻塞是针对时间差而言的。服务器
同步与异步:获取完成标志的方式。若是是采用轮询的方式监测I/O操做是否完成称为同步,而以经过回调通知的方式得到完成标志则称为异步。网络
阻塞与非阻塞:在那段时间差的过程当中,CPU有没有处理别的事情,若是处理过别的事情则是非阻塞,若是并无处理过别的事情则是阻塞。多线程
*1,2表明轮询I/O操做的进行状态,3表明I/O操做已经完成并发
咱们把一个I/O调用看作上面A和B两个过程,A阶段是CPU发出I/O调用【此阶段是十分快速的】,B阶段是相关设备把数据从目标位置转移到用户空间的过程【此阶段就会因为数据量以及数据所在设备的远近而所用时间大为不一样】,容易明白的是上面四个概念都是针对B阶段在数据迁移过程当中此进程/线程所对应的CPU状态而言的,因此用这个过程来看看上面四个概念的组合:异步
1.同步阻塞:便是在B阶段CPU一直采用轮询的方式直到得到完成标志,因此此段时间CPU一直阻塞在此I/O操做上。socket
2.同步不阻塞:在B阶段依然采用轮询的方式直至得到完成标志,可是此轮询不一样于上面的轮询过程,而是在相邻的轮询中完成了上下文切换去处理别的任务的,因此是同步不阻塞高并发
3.异步阻塞:也就是所没有上面的1,2过程,当I/O操做完成后回调通知CPU已完成【便是3过程】,可是此阶段CPU处于休眠状态而不处理别的任务。spa
4.异步不阻塞:和上面同样没有1,2过程而是经过回调知道I/O操做已完成,可是并无休眠,而是在此阶段处理其余任务。线程
综上所述:异步不阻塞是最高效的。
在实际中常采用多线程模拟理想异步非阻塞模式:一个主线程用于计算,多个线程用于执行I/O操做【多是上面四种的任意形式】
几种常见服务器模型:
1.同步式:一次处理一个请求,其他请求处于等待状态
2.每请求/每进程: 为每一个请求启动一个进程【不具有扩展功能,系统志愿有限】
3.每请求/每线程:为每一个请求启动一个线程【每一个线程占必定内存,故受限于内存,还会拖慢服务器】【Apache就是采用的这种方式】
4.事件驱动:Node与Nginx采用事件驱动方式而不建立新线程【省去了线程建立/删除的系统开销以及线程上下文切换,因此可以处理更多的链接】【python的Twisted,Ruby的Event Machine以及Perl的AyEvent也是事件驱动,可是他们并非很成功】
须要注意的是对于高并发【注释1】的程序每每采用“同步非阻塞”而不是“多线程的同步阻塞”,在合理设计任务调度的不一样阶段可以使得并发数远大于并行数,须要注意的是在高并发情况下为每一个任务建立一个线程的开销很大,因此并不采用多线程的同步阻塞。
注释1:并发:同时进行的任务数量
并行:可同时工做的物理资源(CPU核数等等)
另外,有个概念是异步IO,其主要是说在同一线程中当遭遇IO时,并不等待而是执行下面的操做直到IO操做完成后再切回当前,其实就是同步非阻塞
参考:
1:http://blog.jobbole.com/99765/
2:深刻浅出Node.js