python事件循环如何驱动协程_如何在事件循环中将协程打包为正常函数?

因为low_level是一个协程,所以它只能通过运行asyncio事件循环来使用。如果希望能够从运行事件循环的同步代码中调用它,则必须提供一个包装器,该包装器实际启动一个事件循环并运行协程,直到完成:def sync_low_level():

loop = asyncio.get_event_loop()

loop.run_until_complete(low_level())

如果您想从一个函数调用low_level(),该函数是运行事件循环的一部分,让它阻塞两秒钟,但不必使用yield from,答案是您不能这样做。事件循环是单线程的;当执行在一个函数内时,事件循环就会被阻塞。无法处理其他事件或回调。在事件循环中运行的函数将控制权交还给事件循环的唯一方法是1)return2)使用yield from。除非您做这两件事中的一件,否则asyncio.sleep调用low_level将永远无法完成。

现在,我想您可以创建一个全新的事件循环,并使用它从作为默认事件循环一部分运行的协同程序同步运行sleep:import asyncio

loop = asyncio.get_event_loop()

@asyncio.coroutine

def low_level(loop=None):

yield from asyncio.sleep(2, loop=loop)

def sync_low_level():

new_loop = asyncio.new_event_loop()

new_loop.run_until_complete(low_level(loop=new_loop))

@asyncio.coroutine

def user_func():

sync_low_level()

if __name__ == "__main__":

loop.run_until_complete(user_func())

但我真的不知道你为什么要这么做。

如果您只想让low_level像返回Future的方法一样,这样就可以将回调等附加到它,只需将它包装成^{}:loop = asyncio.get_event_loop()

def sleep_done(fut):

print("Done sleeping")

loop.stop()

@asyncio.coroutine

def low_level(loop=None):

yield from asyncio.sleep(2, loop=loop)

def user_func():

fut = asyncio.async(low_level())

fut.add_done_callback(sleep_done)

if __name__ == "__main__":

loop.call_soon(user_func)

loop.run_forever()

输出:<2 second delay>

"Done sleeping"

另外,在示例代码中,应该对low_level和user_func同时使用@asyncio.coroutine装饰符,如^{} docs中所述:A coroutine is a generator that follows certain conventions. For

documentation purposes, all coroutines should be decorated with

@asyncio.coroutine, but this cannot be strictly enforced.

编辑:

以下是来自同步web框架的用户如何在不阻止其他请求的情况下调用应用程序:@asyncio.coroutine

def low_level(loop=None):

yield from asyncio.sleep(2, loop=loop)

def thr_low_level():

loop = asyncio.new_event_loop()

t = threading.Thread(target=loop.run_until_complete, args(low_level(loop=loop),))

t.start()

t.join()

如果一个由Flask处理的请求调用thr_low_level,它将阻塞直到请求完成,但是应该为low_level中进行的所有异步I/O释放GIL,从而允许在单独的线程中处理其他请求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值