首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python异步非阻塞循环

Python异步非阻塞循环
EN

Stack Overflow用户
提问于 2019-07-24 03:49:03
回答 1查看 4.3K关注 0票数 1

(我使用了Python 3.7)

代码语言:javascript
复制
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())

当我执行上面的代码时,结果是

代码语言:javascript
复制
[*] sub1() start
[*] sub1() end
[*] sub2() start
[*] sub2() end
[Finished in 1.7s]

您知道,sub2()是在sub1()完成后启动的。

它似乎不能并行工作。

我想把控制权交给sub2(),直到sub1()完成。

也许我必须在某个地方插入await,但我不知道重点在哪里。

问题

如何执行这两个函数,如并行使用for循环?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-24 04:11:47

正如@KlausD在他的评论中指出的那样,简单地添加async标记并不能有效地使代码真正异步。asyncio需要在for-loops中设置某种断点才能有效地知道何时在函数之间切换。下面是一个可能的解决方案,使用同步函数并在循环的executor (这里的文件)中运行它们:

代码语言:javascript
复制
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操作不得不在函数之间切换,您可能会失去时间。异步功能适用于需要在操作之间等待的大型处理(即执行各种服务器调用,其中必须等待服务器响应;读取多个文件,其中必须依赖硬盘读取速度等)。在这些情况下,异步变得非常有用,因为您可以在线程内切换操作,并确保在开始处理请求或文件之前运行所有调用(从服务器拉出;从硬盘获取文件)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57174971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档