tornado 里面如果用 Requests 或者其他 httpSDK,那么如何非阻塞编程呢?

2019-01-03 17:08:17 +08:00
 whx20202

我知道 tornado 有 AsyncHttpClient,用它 + callback 肯定没错。

但是有的时候我用的可能是 SDK,比如 SDK 访问一个 API,一次 http 请求对面要 2 秒才能响应。

那么如果是 gevent,我理解他有猴子补丁,可以在我网络阻塞的时候,切到别的任务上工作,等到网络连接结束的时候,再切回来。

我的问题是:

  1. tornado 是不是 不能在我使用基于 Http 的 SDK,或者 Requests 库的时候,自动识别我网络请求阻塞了,然后处理别的任务?

  2. 如果在 tornado 下不使用 AsyncHttpClient,达到我的目的呢?

搜了一圈谷歌,全是给我讲 io 多路复用和信号驱动,很少有提到这块相关的

2022 次点击
所在节点    Python
6 条回复
locoz
2019-01-03 17:18:55 +08:00
用异步的 HTTPClient 库就可以了,比如 aiohttp。
如果你用的那个 SDK 本身没有用异步的库,那么你要么把他重写成异步的,要么用类似 asyncio.run_in_executor 的方式去运行。
janxin
2019-01-03 19:13:34 +08:00
不能自动把同步变成异步处理请求,除非是 gevent 那种猴子布丁。用 asyncio.run_in_executor 是新起线程去执行
whx20202
2019-01-03 19:20:52 +08:00
@janxin #2 asyncio.run_in_executor 好的好的,我研究一下。
zhengxiaowai
2019-01-03 19:47:55 +08:00
whx20202
2019-01-03 19:54:45 +08:00
@zhengxiaowai #4 感谢,对我来说明显第二种合适。

> 使用 gen.coroutine 装饰器编写异步函数,如果库本身不支持异步,那么响应任然是阻塞的。

第二种方法,ThreadPoolExecutor,起了一个另外的线程去做事情,能满足我的需求。
之前一直不敢用的原因是,不清楚这种方法,到底是不是在主线程里做的,如果是的那肯定不敢用了么。
现在看了这篇文章,大致明白了。
conn4575
2019-01-04 00:25:22 +08:00
尽量找支持 asyncio 的 sdk,使用 ThreadPoolExecutor 太多的话会主线程的轮循效率

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/523539

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX