(我使用了Python 3.7)
import asyncio
result = 0
async def sub1():
global result
print('[*] sub1() start')
for i in range(1, 10000000):
result += i
print('[*] sub1() end')
async def sub2():
global result
print('[*] sub2() start')
for i in range(10000000, 20000000):
result += i
print('[*] sub2() end')
async def main():
await asyncio.gather(
asyncio.create_task(sub1()),
asyncio.create_task(sub2()),
)
asyncio.run(main())当我执行上面的代码时,结果是
[*] sub1() start
[*] sub1() end
[*] sub2() start
[*] sub2() end
[Finished in 1.7s]您知道,sub2()是在sub1()完成后启动的。
它似乎不能并行工作。
我想把控制权交给sub2(),直到sub1()完成。
也许我必须在某个地方插入await,但我不知道重点在哪里。
问题
如何执行这两个函数,如并行使用for循环?
谢谢。
发布于 2019-07-24 04:11:47
正如@KlausD在他的评论中指出的那样,简单地添加async标记并不能有效地使代码真正异步。asyncio需要在for-loops中设置某种断点才能有效地知道何时在函数之间切换。下面是一个可能的解决方案,使用同步函数并在循环的executor (这里的文件)中运行它们:
import asyncio
result = 0
def sub1():
global result
print('[*] sub1() start')
for i in range(1, 10000000):
result += i
print('[*] sub1() end')
def sub2():
global result
print('[*] sub2() start')
for i in range(10000000, 20000000):
result += i
print('[*] sub2() end')
async def main(loop):
res = await asyncio.gather(
loop.run_in_executor(None, sub1),
loop.run_in_executor(None, sub2)
)
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))值得注意的是,要编写异步代码,必须记住参与确保代码实际异步运行的实践。Python中的本机for-loop实际上是一段同步代码,因此当调用函数时,for -循环一直运行到完成,然后在线程中为下一次操作腾出空间。
另一件事是,由于您的代码是简单的添加,您实际上并不是通过异步运行它来节省任何时间。糟糕的是,由于asyncio操作不得不在函数之间切换,您可能会失去时间。异步功能适用于需要在操作之间等待的大型处理(即执行各种服务器调用,其中必须等待服务器响应;读取多个文件,其中必须依赖硬盘读取速度等)。在这些情况下,异步变得非常有用,因为您可以在线程内切换操作,并确保在开始处理请求或文件之前运行所有调用(从服务器拉出;从硬盘获取文件)。
https://stackoverflow.com/questions/57174971
复制相似问题