首页 > tornado关于协程疑问

tornado关于协程疑问

tornado的协程,使用场景就究竟是什么呢?还有异步与协程最大的区别呢?tornado的异步非阻塞究竟是指网络操作的io呢,还是数据库这种io操作呢?

新手菜鸟...大家多多包涵


使用协程的场景主要就是处理io。异步和协程不是同一类概念,不能说最大的区别是什么。协程是加强版生成器,只是实现异步的一种方案。也可以用线程,进城实现异步io,基本上跑不了epoll等函数。只要是io操作,基本都有延时,不管是网络还是本地文件读写,所以都适用异步io。

如果需要看参考书,推荐unix网络编程,只用看相关概念即可,比如几种常见的io模型,阻塞与非阻塞,同步和异步的概念。


同步和异步

异步的概念相对于同步,主要指程序执行的时候,普通函数调用与系统调用执行的运行状态。

在网络IO,通常需要系统调用accept获取连接和read获取数据。并且由于IO比较耗时,所以这两个系统调用到返回用户代码就存在阻塞和非阻塞。下面以read调用为例:

# 读取网络数据系统调用
data = read()   

# 执行任务A
A.task()

对于同步模型,read函数调用之后,用户代码就无法往下执行A,用户进程就休眠了。操作系统进程则在进行缓存区数据的等待和读取,直到系统的read函数调用返回数据之后,用户进程才从休眠中醒来。然后执行A.task

对于异步模型,read函数调用之后,会向系统注册一个回调函数,用户进程并没有休眠,而是继续往下执行A.task,与此同时,操作系统的进程与同步模型时候的一样,也在等待数据和读取。只不过此时,操作系统的readA.task他们之间并没有先后顺序,而是各种执行各自的逻辑。看起来就是不同(异)的函数在执行(步)。当操作系统read执行完毕就会回调通知用户进程,并把数据返回。

异步和协程

异步和协程不能完全等同,他们的相似点都是函数执行的一种方式。协程,顾名思义就是协商程序(函数)。通常函数执行之后,要么返回,要么阻塞,阻塞一定条件之后返回。协程的函数则是函数执行到某个逻辑,设置一执行点,然后返回控制权,一旦某些条件满足了,再从刚设置的执行点进行接下来的函数逻辑,最后才返回。python中通常使用yield实现。这种执行流和异步很像。例如:


def get():
    # 读取网络数据系统调用
    data = yield read()   

    # 执行任务A
    A.task(data)

def post():
    pass

协程和异步的实现效果类似,调用read后不会阻塞,而是返回控制权。对于get中,还是不能执行A.task,直到read数据到达,然后再从yield执行,最后执行A。这个流程与同步的差别在于,如果是同步,不仅是A无法执行,别的地方的代码也无法执行,比如 post中的逻辑。而协程的调用时候,get中的A.task无法执行,可是post中的其他代码是可以执行的。同步和异步对比中,看问题的观察点是get函数内,协程的观察点是get和post函数。

tornado的io

tornado的IO指的是处理网络连接的异步,即epoll(kqueue)方式处理连接。如果tornado的handler的单个请求中查询数据库,这里的IO就类似 get的read操作。既可以是同步,也可以是异步。只不过,如果这里使用了阻塞IO,那么整个tornado进程处理网络IO的时候,也会阻塞。

【热门文章】
【热门文章】