Python中关于协程asyncio的一个问题
import asyncio
def foo(n):
print(f’--------- foo({n}) ----------’)
async def main(loop):
loop.call_later(0.1, foo, 1)
loop.call_soon(foo, 2)
loop.call_at(loop.time() + 0.2, foo, 3)
await asyncio.sleep(1)
event_loop = asyncio.get_event_loop()
try:
event_loop.run_until_complete(main(event_loop))
finally:
event_loop.close()
有如上这段简单的代码.
在 main 函数中有 await asyncio.sleep(1) ,如果不写一行, 那么 loop.call_later(0.1, foo, 1) 和 loop.call_at(loop.time() + 0.2, foo, 3) 的结果都会看不到(sleep 的时间必须大于 delay 的时间), 这是为什么.
我的疑问在这里, Python asyncio 的事件循环机制是什么, event_loop.run_until_complete(main(event_loop)) , 这里的 run_until_complete 指的
到底是什么 complete ?
或者说有讲解 Python asyncio event loop 的好的资料告诉我也好.
Python中关于协程asyncio的一个问题
我无法理解你的问题
main 函数返回,不是所有事件完成,没有 sleep,main 函数返回 ioloop 就结束了啊,call_later 自然不会执行
显然 run_until_complete 指的是你传入的 main()结束
可以看下这个: https://docs.python.org/3/library/asyncio-eventloop.html
run_until_complete 是指一个 future 运行为一个周期,也就是你传入的 main(event_loop),当没加入 await asynico.sleep()时,run_until_complete 会直接运行完 main(event_loop)然后就执行到你的 event_loop.close()直接关闭事件循环。而你代码中的 loop.call_*是把任务转交给 event_loop 运行,此时的 event_loop 已经关闭,就无法运行了。你可以使用 run_forever()保持事件循环不关闭
也就是说 我另外的 两个 loop.call_* 是另外的两个 future ,对吧.
其实道理不难,就是绕人,我就不献丑了
推荐《 fluent python 》虽然只用了一章讲协程,不过够了
流畅的 py 我已经读了两遍了.
恩恩,差不多可以这样理解,不过 await asyncio.wait(tasks)就不一样了还是属于 main 的 future。
谢谢了.
aio 建议从 3.4 走一遍。那时还没有 await。这玩意其实就是 yield 和 yield from。搞懂了就 ok 了。
不过用了一遍之后,可能还是大坑。
为啥不用 gevent 呢?
我觉得你说的很虚, linux 的 epoll 我知道,当初在看 node 以及 libuv 的时候学了.
我想反问,如果你会汇编,难道所有语言对你都是小 case 吗. 所以啊,别说的这么轻浮.
你说的这个我在读流畅的 py 的时候就已经很熟悉了. 为什么不用 gevent, 很简单,我现在还是学生.
是学生就好好学吧。加油
额,那不如看看 asyncio 源码吧,我觉得应该是没有预激的原因
说不定是个 bug,研究清楚可以提个 issue
或者先用最新的再试试,3.7 改了很多接口,兴许解决了这些逻辑问题
额,我就是用的 Python3.7, 准备这两天看一下资料,然后总结一下.
认同 so1n 的说法
之前写过一个非常简单(残疾)地 gevent demo,一百行左右,感觉可以帮助楼主理解 asyncio/gevent 等
https://gist.github.com/cosven/a251ca10c6c0c57c8b5dbd92fe131c2f
在 LZ 的例子中:main 是个协程,另外 call_later/call_soon/call_at 也会创建协程。后来,run_until_complete 只等待 main 结束,就关闭了 event_loop,当 event_loop 关闭了,其它协程自然就不会执行了。
如果 LZ 想让这几个协程都能执行完,可以用 loop.run_forever() 或者一些 asyncio.wait 等其它方法。
恩,没错呢.
这玩意就是模仿现在 js dart 之类的 异步对象
python 以前也有个别扭的 future 库
他们要实现的功能都差不多 js dart 是原声实现 。
Python 靠 yied 实现
但是万变不离其宗 搞清楚目的就很好理解了
Python3 我没用过 瞎说的 2333


