使用 asyncio 定期调用依赖于 IO 的函数
Using asycio to periodically call a function with a periodicy that depends on IO
我正在构建一个 DJ 灯光系统,其中包含以特定节拍间隔触发的事件(即在下一节拍之间的中间闪光灯)。 bpm(每分钟节拍)根据外部应用程序而变化,永远不能假定为固定的。
我想安排一堆 IO 操作(闪光灯、触发激光)在下一节拍中发生,方法是在下一节拍开始前 运行ing 一个 scheduling_function
几毫秒击败.
我知道以 event_loop
时间单位表示的时间,我希望函数达到 运行(由 get_next_time_to_run()
返回)。
我尝试使用 event_loop.call_at()
函数,通过递归调用,在下一节拍之前连续安排 scheduling_function
为 运行。但是,我得到一个 RecursionError。
有什么更好的设置方法。这是我当前的代码:
def schedule_next_frame():
"""This function is schedules the next frame (light, motor, lasers). It is trigged to run just before the next beat to give it time to prepare"""
set_up_frame() #actual scheduling of IO
frame += 1
time_to_run = get_next_time_to_run(frame-0.1)
loop.call_at(time_to_run, schedule_next_frame(frame))
print("Beginning YettiCubes2.0")
frame = get_current_beat()+1 #FIXME if this is really close to a beat boundary, we might tick over a beat before we can setup the next frame
loop.call_soon(schedule_next_frame())
loop.run_forever()
您想在指定时间告诉 asyncio 到 运行 schedule_next_frame(frame)
。以下代码不会这样做:
loop.call_at(time_to_run, schedule_next_frame(frame))
相反,它首先递归调用 schedule_next_frame
,然后将调用结果传递给 call_at
。由于递归是无限的,因此永远不会有任何结果,而是会出现异常。
告诉call_at
到运行schedule_next_frame(frame)
的正确方法是:
loop.call_at(time_to_run, lambda: schedule_next_frame(frame))
lambda
表达式将生成一个函数,当不带参数调用该函数时,会调用 schedule_next_frame(frame)
.
我正在构建一个 DJ 灯光系统,其中包含以特定节拍间隔触发的事件(即在下一节拍之间的中间闪光灯)。 bpm(每分钟节拍)根据外部应用程序而变化,永远不能假定为固定的。
我想安排一堆 IO 操作(闪光灯、触发激光)在下一节拍中发生,方法是在下一节拍开始前 运行ing 一个 scheduling_function
几毫秒击败.
我知道以 event_loop
时间单位表示的时间,我希望函数达到 运行(由 get_next_time_to_run()
返回)。
我尝试使用 event_loop.call_at()
函数,通过递归调用,在下一节拍之前连续安排 scheduling_function
为 运行。但是,我得到一个 RecursionError。
有什么更好的设置方法。这是我当前的代码:
def schedule_next_frame():
"""This function is schedules the next frame (light, motor, lasers). It is trigged to run just before the next beat to give it time to prepare"""
set_up_frame() #actual scheduling of IO
frame += 1
time_to_run = get_next_time_to_run(frame-0.1)
loop.call_at(time_to_run, schedule_next_frame(frame))
print("Beginning YettiCubes2.0")
frame = get_current_beat()+1 #FIXME if this is really close to a beat boundary, we might tick over a beat before we can setup the next frame
loop.call_soon(schedule_next_frame())
loop.run_forever()
您想在指定时间告诉 asyncio 到 运行 schedule_next_frame(frame)
。以下代码不会这样做:
loop.call_at(time_to_run, schedule_next_frame(frame))
相反,它首先递归调用 schedule_next_frame
,然后将调用结果传递给 call_at
。由于递归是无限的,因此永远不会有任何结果,而是会出现异常。
告诉call_at
到运行schedule_next_frame(frame)
的正确方法是:
loop.call_at(time_to_run, lambda: schedule_next_frame(frame))
lambda
表达式将生成一个函数,当不带参数调用该函数时,会调用 schedule_next_frame(frame)
.