Max*_*nar 14 python asynchronous gevent python-3.x python-asyncio
我最近偶然发现了混淆gevent和基于asyncio的代码的问题,因为当我用猴子修补它们时,某些同步库可以很好地工作gevent.monkey.patch_all()
。我找到了该aiogevent
库,该库似乎对实现PEP 3156有所帮助,并将asyncio事件循环替换为您选择的其他实现(在本例中为gevent)。我发现的git仓库的最后一次重大提交是在4年前。修复setup.py之后,我设法成功安装了它,但是问题是它没有通过所有测试。
这些测试之一是test_soon,它产生应该执行操作并停止循环的greenlet。该测试将永远挂起,因为loop.stop()
对循环没有任何影响,该循环预计将在所有任务完成后停止。我写了两个代码片段来检查它是否在传统的协程中发生,而另一个则通过来检查gevent.spawn
。
import gevent
import aiogevent
import asyncio
asyncio.set_event_loop_policy(aiogevent.EventLoopPolicy())
loop = asyncio.get_event_loop()
async def func():
print('bloop')
loop.stop()
loop.create_task(func())
loop.run_forever() # works alright and stops as soon as func finish
Run Code Online (Sandbox Code Playgroud)
和gevent.spawn
:
import gevent
import aiogevent
import asyncio
asyncio.set_event_loop_policy(aiogevent.EventLoopPolicy())
loop = asyncio.get_event_loop()
def func():
print('bloop')
loop.stop()
g = gevent.spawn(func)
loop.run_forever() # func is executed as soon as loop runs, but loop.stop() is ignored
Run Code Online (Sandbox Code Playgroud)
问题是:这里可能出什么问题?我清楚地看到,在启动循环之后,greenlet会运行,但是循环是否“未跟踪”?我在异步源中找不到与该机制相对应的确切行,对于gevent来说也是如此-我对这些模块的内部并不十分熟悉,并且通过它们进行搜索令人困惑,但是我想知道有什么区别和aiogevent
为了通过测试,必须对事件循环进行哪些更改。
upd1:为了强调该问题,gevent.hub.Hub
没有“公共”句柄来停止循环,只有那些应该完全销毁它的循环(gevent.hub.get_hub().destroy()
当前无效,并且如果未在MAIN greenlet中调用,则尝试加入集线器greenlet将会失败)。当循环退出(gevent.exceptions.LoopExit
)时,它确实会引发内部异常。我的想法是找到如何捕获此异常的方法,并将其与run_forever绑定在一起,但尚无结果。
小智 -2
为什么不使用这样的 while 循环:
from time import sleep
while(1 == 1):
print('bloop')
sleep(1)
Run Code Online (Sandbox Code Playgroud)
这将打印 bloop 等待一秒钟,然后再次打印(因为 1 = 1),如果我错了,请原谅我,并且你必须使用你正在使用的函数,但我尽了最大努力。
归档时间: |
|
查看次数: |
275 次 |
最近记录: |