gpt4 book ai didi

python-asyncio - 使用 asyncio 做多项终极工作

转载 作者:行者123 更新时间:2023-12-04 10:35:49 25 4
gpt4 key购买 nike

有 2 个工作:“wash_clothes”(job1) 和“setup_cleaning_robot”(job2),每个工作需要你 7 和 3 秒,你必须做到世界末日。

这是我的代码:

import asyncio


async def wash_clothes():
print(f'Start job1')
await asyncio.sleep(3)
print(f'Finish job1, took 3 seconds')


async def setup_cleaning_robot():
print(f'Start job2')
await asyncio.sleep(7)
print(f'Finish job2, took 7 seconds')


async def not_really_asyncio():
kk = 1
while True:
job_list = [wash_clothes(), setup_robot()]
await asyncio.gather(*job_list)
kk += 1


async def main():
await not_really_asyncio()
# await really_asyncio() # Still don't know how to do


if __name__ == '__main__':
asyncio.run(main())

这是输出
Start job1
Start job2
Finish job1, took 3 seconds
Finish job2, took 7 seconds
Start job1
Start job2
Finish job1, took 3 seconds
Finish job2, took 7 seconds
...
...

但是我们知道我们可以把衣服放好,然后设置清洁机器人,休息一下(只有几秒钟),直到其中一项工作完成,然后现在就去做,一次又一次……

正确的输出如下:
Start job1
Start job2
Finish job1, took 3 seconds
Start job1
Finish job1, took 3 seconds
Start job1
Finish job2, took 7 seconds
Start job2
Finish job1, took 3 seconds
...
...

现在我有一个使用线程的想法,但它会弄乱我的代码。

我希望代码尽可能简洁

最佳答案

您希望当前代码中没有发生的关键事情是,当洗完衣服时,即使清洁机器人仍在进行中(并且将再持续 4 秒),您也会立即再次开始洗衣服。但是这里的这一行阻止了:

async def not_really_asyncio():
kk = 1
while True:
job_list = [wash_clothes(), setup_robot()]
await asyncio.gather(*job_list) # <--- Waits until *both* finish
kk += 1
asyncio.gather等到所有作业完成。所以即使 wash_clothes已完成, gather会继续只是坐在那里等待 setup_robot也完成。

我可以想到两种方法来解决这个问题。
  • while循环,使用 asyncio.wait() 而不是 gather .这允许您等到其中一个任务完成,此时您可以立即启动它的另一个实例。

    这是修复当前代码的最直接方法。然而,这很棘手:asyncio.wait()非常繁琐(它的参数是任务而不是协程,你必须挑选它的返回值)和你的 while loop 将只需要运行那些尚未运行的任务。
  • 更横向的想法是使用单独的 while对两个任务中的每一个进行循环。您可以将它们放在单独的函数中或直接放在 wash_clothes() 中。和 setup_cleaning_robot()职能。

  • 像这样:
    counter = 0

    async def keep_washing_clothes():
    while True:
    await wash_clothes()
    global counter
    counter += 1

    async def keep_setting_up_cleaning_robot():
    while True:
    await setup_cleaning_robot()
    global counter
    counter += 1

    async def really_asyncio():
    job_list = [keep_washing_clothes(), keep_setting_up_cleaning_robot()]
    await asyncio.gather(*job_list)

    奖金闲聊如果您将时间戳放在 print() 中,您可能会发现更容易理解发生了什么。输出:
    # At the start of your script:
    from datetime import datetime

    # Later on:
    print(datetime.utcnow().isoformat(), 'Finish job2, took 7 seconds')

    关于python-asyncio - 使用 asyncio 做多项终极工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60187221/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com