web开发异步理解
并发:
web服务多有IO密集行操作,IO效率会直接影响接口性能。首先可以通过多线程并发处理,其次可以通过多进程并行,现在流行起来异步server,由事件驱动,可以更大应用每一核CPU的性能,发展到协程,使异步server开发更直观。
- 进程: 系统进行资源分配和调度的基本单位,是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)
- 线程: 有时被称为轻量级进程,是程序执行流的最小单元。线程的实体包括程序、数据和TCB(动态特性由线程控制块)(用于指示被执行指令序列的程序计数器、保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈)
每一个进程和线程都是同步执行的,并且有CPU调度,当发生阻塞时,切换都需要陷入系统调用(system call),先让CPU跑操作系统的调度程序,然后再由调度程序决定该跑哪一个进程(线程),消耗较大。
由于线程的抢占式调度,使线程存在执行顺序无法确定的特点,同步问题不宜处理。对进程中共享资源的抢占,加锁保证线程安全也比较复杂。
- 事件驱动: 当单核CPU性能提升,可以通过应用层程序预先设计一个事件循环,这个事件循环程序不断地检查目前要处理的信息(例如epoll的文件标识符和socket),根据要处理的信息运行一个触发函数。将阻塞的IO通过异步回调解决。
- 协程: 协程是一种用户级的轻量级线程。拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。
- 因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。
协程可以有效解决异步+回调方式编程带来的的异常难以定位的堆栈撕裂问题。
协程优劣:
优势:
- 无需线程上下文切换的开销
- 无需原子操作锁定及同步的开销
- 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。
缺点:
- 无法利用多核资源:协程的本质是个单线程,它不能同时将单个CPU的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。
- 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序:这一点和事件驱动一样,可以使用异步IO操作来解决。