使用asycio定期调用具有依赖于IO

时间:2018-04-13 20:36:13

标签: python python-asyncio

我正在构建一个DJ照明系统,其中包含以特定节拍间隔触发的事件(即在下一拍之间的闪光频闪中途)。 bpm(每分钟节拍)根据外部应用程序而变化,永远不会被认为是固定的。

我想通过在下一个节拍开始前几毫秒运行scheduling_function来安排一系列IO操作(闪光灯频闪,触发激光)在下一拍中发生。

我知道时间,以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()

1 个答案:

答案 0 :(得分:1)

您想告诉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)