gpt4 book ai didi

python - 在一个时间间隔内运行一个 Asyncio 循环

转载 作者:太空宇宙 更新时间:2023-11-03 15:29:55 46 4
gpt4 key购买 nike

目标:运行main()start_time 之间的一堆异步函数组成和 end_time

import datetime as dt

start_time, end_time= dt.time(9, 29), dt.time(16, 20)

current_time()只是不断将当前时间添加到工作空间。此时间用于此处未显示的脚本中的几个不同点

async def current_time(): 
while True:
globals()['now'] = dt.datetime.now().replace(microsecond=0)
await asyncio.sleep(.001)

另一个做某事的函数:

async def balance_check():
while True:
#do something here
await asyncio.sleep(.001)

main()等待之前的协程:

async def main():
while True:
#Issue:This is my issue. I am trying to make these
#coroutines only run between start_time and end_time.
#Outside this interval, I want the loop to
#shut down and for the script to stop.
if start_time < now.time() < end_time :

await asyncio.wait([
current_time(),
balance_check(),
])
else:
print('loop stopped since {} is outside {} and {}'.format(now, start_time, end_time))
loop.stop()


loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(main())
finally:
loop.close()

问题:这甚至在 end_time 之后仍然有效

最佳答案

问题是 await asyncio.wait([current_time(), balance_check(),]) 的使用不正确。

等待 asyncio.wait() 等待指定的可等待对象完成,即返回值或引发异常。由于 current_timebalance_check 都不会从它们的无限循环中返回,因此 main() 的执行永远不会通过 await asyncio.wait (...),因为此表达式等待两者完成。反过来,main() 中的 while 循环永远不会进行第二次迭代,并且 loop.stop() 也没有机会运行。

如果代码的目的是使用 asyncio.wait() 来为协程提供运行的机会,那么 asyncio.wait 不是实现该目的的工具。相反,可以通过调用 asyncio.create_task() 来启动这两个任务,然后什么都不做。只要事件循环可以运行(即它不会被 time.sleep() 或类似的调用阻塞),asyncio 将自动在协程之间切换,在本例中为 current_timebalanced_check 以大约 1 毫秒的速度。当然,您会希望在 end_time 截止日期之前重新获得控制权,因此“什么都不做”最好表示为对 asyncio.sleep() 的一次调用:

async def main():
t1 = asyncio.create_task(current_time())
t2 = asyncio.create_task(balance_check())
end = dt.datetime.combine(dt.date.today(), end_time)
now = dt.datetime.now()
await asyncio.sleep((end - now).total_seconds())
print('loop stopped since {} is outside {} and {}'.format(now, start_time, end_time))
t1.cancel()
t2.cancel()

请注意,显式的 loop.stop() 甚至不是必需的,因为 run_until_complete() 将在给定协程完成后自动停止循环。在任务上调用 cancel() 没有实际效果,因为循环几乎立即停止;包含它是为了使这些任务完成,以便垃圾收集器不会警告销毁挂起的任务。

如评论中所述,此代码不等待 start_time,但通过在生成任务之前添加另一个 sleep 可以轻松实现该功能。

关于python - 在一个时间间隔内运行一个 Asyncio 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58633368/

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