gpt4 book ai didi

python - asyncio.sleep 如何处理负值?

转载 作者:太空狗 更新时间:2023-10-30 01:57:28 28 4
gpt4 key购买 nike

我决定使用 Python 的 asyncio 实现 sleep 排序 ( https://rosettacode.org/wiki/Sorting_algorithms/Sleep_sort ),当时我有一个奇怪的发现:它适用于负值(并立即返回 0)!

这是代码(你可以在这里运行 https://repl.it/DYTZ ):

import asyncio
import random

async def sleepy(value):
return await asyncio.sleep(value, result=value)


async def main(input_values):
result = []
for sleeper in asyncio.as_completed(map(sleepy, input_values)):
result.append(await sleeper)
print(result)


if __name__ == '__main__':
loop = asyncio.get_event_loop()
input_values = list(range(-5, 6))
random.shuffle(input_values)
loop.run_until_complete(main(input_values))

如预期的那样,代码执行需要 5 秒,但结果始终是 [0, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5] 。我可以理解 0 立即返回,但负值如何以正确的顺序返回?

最佳答案

好吧,看看 source :

  • delay == 0 是特殊情况下立即返回,它甚至不会尝试休眠。
  • 非零延迟调用 events.get_event_loop()。由于在 asyncio.tasks 中没有对 events.set_event_loop_policy(policy) 的调用,它似乎会退回到默认值,除非它已经在其他地方设置,并且 the default is asyncio.DefaultEventLoopPolicy .
  • 这在 events.py 中没有定义,因为它在 WindowsUNIX 上不同。
  • 无论哪种方式,sleep 都会调用 loop.create_future()。这在 base_events.BaseEventLoop 中定义了一些继承。这只是对 Future() 构造函数的简单调用,没有重要的逻辑。
  • 它从 Future 的实例委托(delegate)回循环,如下所示:

    future._loop.call_later(delay,
    futures._set_result_unless_cancelled,
    future, result)
  • 那个也在 BaseEventLoop 中,但仍然不直接处理 delay 数:它调用 self.call_at,添加当前时间延迟。
  • call_at 调度并返回一个events.TimerHandle,回调是告诉Future它已经完成了。返回值仅在要取消任务时才相关,它会自动在结束时进行清理。日程安排很重要。
  • _scheduled 通过 heapq 排序 - 一切都按排序顺序进行,计时器按它们的 _when 排序。这是关键。
  • 每次检查时,它都会剔除所有已取消的预定事件,然后按顺序运行所有剩余的预定回调,直到遇到未就绪的回调。

长话短说:

asyncio 一起休眠负持续时间安排任务在过去“准备好”。这意味着它们会到达计划任务列表的顶部,并在事件循环检查后立即运行。实际上,0 排在第一位,因为它甚至没有进行调度,但其他所有内容都会向调度程序注册为“迟到”,并按照迟到的顺序立即处理。

关于python - asyncio.sleep 如何处理负值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39398312/

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