多语言展示
当前在线:491今日阅读:26今日分享:39

Python Tornado如何在IOLoop中异步调用阻塞方法

介绍Python 3.6环境下,使用Tornado如何给IOLoop添加Callback,以及如何在Callback中异步调用阻塞方法。异步调用阻塞方法的好处是,不用改写阻塞方法为非阻塞,阻塞式的程序库还能用;而且由于在新线程中执行,不影响主IOLoop循环。
工具/原料
1

Python 3.6

2

Tornado 5.1 Package

方法/步骤
1

首先,以一个如图所示的最简单Tornado样例程序为例,监听指定端口,处理一个main页面请求。

2

现在,我们有一个get_person函数,是发送Http请求获取页面。使用的是requests包中的阻塞式http获取。

3

调用这个阻塞式函数的函数,同样也是阻塞式的。所有类似这种的阻塞式函数,都没法直接异步调用,不能直接使用async-await方式。

4

所以,首先编写一个异步方法,并声明为async方法。在异步方法中,每次调用阻塞方法处,使用IOLoop.current()的run_in_executor函数自动在新线程运行,使用await等待这个操作(运行结束后await结束)。这样就把阻塞方法变成了非阻塞。

5

至于run_in_executor函数,第一个参数设置为None即可,第二个是要运行的阻塞函数名,第三个是这个阻塞函数的函数参数。

6

有了异步非阻塞的方法,回到Tornado的web代码,添加一个/start的处理类。在处理函数中,使用IOLoop.instance()获取当前IOLoop,使用add_callback添加函数回调为刚才编写的异步方法。(IOLoop运行后就会调用该函数)。

7

打开Firefox,在地址栏输入localhost:端口号/start,回车,即可看到程序即将启动字样。

8

回到python的输出窗口,可以看到非阻塞方法已经开始运行,而且此时IOLoop也能处理网络请求,两不误。

注意事项

Tornado自带非阻塞的httpclient,如果不用考虑旧代码兼容性问题,全部使用非阻塞代码更好。

推荐信息