我正在使用异步的网络框架。
在下面的代码中(low_level
是我们的低级函数,main
块是我们的程序项,user_func
是用户定义的函数):
import asyncio
loop = asyncio.get_event_loop()
""":type :asyncio.AbstractEventLoop"""
def low_level():
yield from asyncio.sleep(2)
def user_func():
yield from low_level()
if __name__ == '__main__':
co = user_func()
loop.run_until_complete(co)
我希望将low_level
包装为正常函数,而不是coroutine
(用于compatibility
等),但是low_level
处于事件循环中。如何把它包装成一个正常的函数?
因为
low_level
是一个协程,所以它只能通过运行asyncio
事件循环来使用。如果希望能够从运行事件循环的同步代码中调用它,则必须提供一个包装器,该包装器实际启动一个事件循环并运行协程,直到完成:如果您想从一个函数调用
low_level()
,该函数是运行事件循环的一部分,让它阻塞两秒钟,但不必使用yield from
,答案是您不能这样做。事件循环是单线程的;当执行在一个函数内时,事件循环就会被阻塞。无法处理其他事件或回调。在事件循环中运行的函数将控制权交还给事件循环的唯一方法是1)return
2)使用yield from
。除非您做这两件事中的一件,否则asyncio.sleep
调用low_level
将永远无法完成。现在,我想您可以创建一个全新的事件循环,并使用它从作为默认事件循环一部分运行的协同程序同步运行sleep:
但我真的不知道你为什么要这么做。
如果您只想让} :
low_level
像返回Future
的方法一样,这样就可以将回调等附加到它,只需将它包装成^{输出:
另外,在示例代码中,应该对} docs 中所述:
low_level
和user_func
同时使用@asyncio.coroutine
装饰符,如^{编辑:
以下是来自同步web框架的用户如何在不阻止其他请求的情况下调用应用程序:
如果一个由Flask处理的请求调用
thr_low_level
,它将阻塞直到请求完成,但是应该为low_level
中进行的所有异步I/O释放GIL,从而允许在单独的线程中处理其他请求。相关问题 更多 >
编程相关推荐