loop = asyncio.get_event_loop()
exerciseId = [1,2,3]
// once 为协程
tasks = [once(i) for i in exerciseId]
loop.run_until_complete(asyncio.gather(*tasks))
Expected: 执行顺序是 once(1),once(2),once(3)
In fact: 是无序的,譬如是 2,3,1 的顺序
于是去查看 asyncio.gather 源码的时候,发现这么一行代码:for arg in set(coros_or_futures):
。这个函数对列表 tasks 先进行了一次 set()操作,而 set 在 python 里是通过 hash 实现的,所以导致的无序是么?
那现在我希望按列表里的顺序进行添加 Task 操作,有什么好的办法呢?
1
n329291362 2017-11-25 00:41:22 +08:00 via iPhone
同步运行就有顺序了?
|
2
NoAnyLove 2017-11-25 01:09:02 +08:00 1
如果想要按照顺序依次添加,那就依次实例化 asyncio.Task 就行了。
tasks = [asyncio.Task(once(i)) for i in exerciseId] 或者依次调用 ensure_future 也行, tasks = [asyncio.ensure_future(once(i)) for i in exerciseId] |
5
owenliang 2017-11-25 08:27:28 +08:00 via Android
python 真是强行异步,晦涩啊
|
7
iyaozhen 2017-11-25 11:25:01 +08:00 via Android
话说你用了协程这几个任务应该不需要有先后的依赖吧。
|
8
wisej OP @iyaozhen 是的,协程之间没有先后的依赖。但是他们的完成需要两个参数,p1,p2.p1 就是问题描述中 exerciseId 列表内的元素,p2 是个常数。问题是,exerciseId 内第一个元素对应的就是 p2,之后 exerciseId 每迭代一次,p2 自增 1.
之前写同步代码时,就是迭代列表 exerciseId,执行函数,自增 1.但是异步之后,由于函数的执行不是按列表的顺序,而是无序的,就会导致 p1 p2 对应出错。 在 V 友给出方案之前,我只好建立个字典,提前把 p1、p2 映射关系算出来保存。 所以就是:也可以不需要有先后依赖,但是按顺序来的话,会比较省事,不用改原来的代码 |