Skip to content

9月19日学习笔记

lirui edited this page Sep 20, 2020 · 3 revisions

第二十一讲 异步编程

21.1 Background

多任务:

非抢占性调度:除非主动放弃,否则OS拿不到控制权,早期windows

抢占式多任务,eg.linux、Unix,不论是否愿意放弃,都强行打断,通过中断或异常来打断当前进程的执行,能够让OS获得控制权,OS可以完成对资源的管理和调度

用户态实现调度,或者实现上下文切换,在一个进程里面,会存在多个用户级调度的线程,类似协程,调度不依赖操作系统,在用户态实现调度,没有了用户态和内核态之间的切换,会更快,用的栈也会小一些,

但是缺点:1、栈的总容量还是会增加,2、不同平台需要考虑硬件的差异性;

kernel-supported Threads 内核支持的线程或者进程

需要OS来进行调度,用户级的线程的缺陷就没有了,比如说,用户级线程从一个CPU切换到另一个CPU,在内核中实现比较简单,用户态实现比较困难了,虽然管理调度更加方便了,耗的资源也会更大一些,首先要从用户态切到内核中来,第二,内核中要维护相应的内核栈、用户栈,空间也会进一步增加,相对来说,通用性更好,并行性也不错,但是时间和空间开销相对大一些

什么是异步?

异步和并行/并发还是有些不同的,并行:两个任务分别在两个CPU上运行,Concurrent 并发,只有一个CPU,在一个有限时间段之内,这两个任务先后得到了执行,时间很短,给人一种错觉,像是并行

异步,在某种程度上能体现并行/并发,但是它是一种语言和一种编程的方法,这种方法能够达成一种更加高效的结果,

同步,claim发出一个请求,kernel或者server负责响应,响应需要花很长时间,响应回去之后才能开始第二个任务的执行

异步:第一个任务发出请求,执行完毕返回,在这个过程中,第二个任务也发出了请求,它的返回在这,两个任务之间产生一个交叉和重叠,发出一个请求之后能够迅速返回,响应还没有完成,迅速返回了,响应在未来某个时间完成

异步时间效率会很高

1999年,Internet出现,web1.0 OK,web2.0 Cry!

C10K problem

在现有硬件下解决这个问题

核心问题:时间开销+空间开销

Apache采取的是一种类似于多线程的处理方式,内核可以进行调度和切换的线程,当来了一个请求,专门开辟一个thread来和这个连接请求进行交互,来执行后续的read、write、receive操作,来一个connect就会有一个线程,有多少个并发connect就会有多少个并发thread,随着thread个数增加,thread所占开销就会非常大,使得在一台机器上,很难支持大规模的连接请求,这是为什么apache性能低的原因,时间和空间都撑不起来,

nginx为什么性能高呢,有3个CPU,就有3个worker,每一个worker是一个process,也就是有多少个worker就有多少个process,有多少CPU就有多少个process,来了一个请求,在一个process里面会只有一个thread,内核只能看到一个thread,来了一个请求,在这个thread里面划分一个task来响应这个请求,来了第二个请求,第二个task出来了,这个task内核是不知道的,task之间的切换靠事件编程机制,来了一个claim之后,里面会有一个小的状态机跟这个claim进行交互,再来一个claim,下一个状态机又和它进行交互,形成了不同的状态机,来支持不同类型的claim,基于状态机就不需要进行线程切换,

Clone this wiki locally