在while循环中使用python的core.Clock.GetTime()方法:定时失真?

时间:2018-02-14 02:21:07

标签: python time while-loop sleep psychopy

我在心理论坛上讨论计时精度时遇到了一个有趣的问题(psychopy是一个用python编写的心理学软件)。这是问题所在:

timer=core.Clock()#instantiate a clock
stimulus.draw()#draw stimulus
win.flip()#flip the monitor to make stimulus appear
Routine = True
While Routine:
    key_press = event.getKeys(keyList=["f", "j"])#check keyboard's buffer
    if len(key_press) > 0:#keypress detected!
       RT = timer.getTime()#record response time
       Routine = False

我被告知在while循环中调用getTime()可能很危险:“一个非常紧凑的循环占用了所有CPU时间,阻塞了其他进程,这可能最终会中断并占用控制权虽然要完成积压工作,但要完全弄清楚你的时间安排。在每次迭代中,调用类似time.sleep(0.001)的东西来为其他进程腾出时间。“我不明白为什么会这样。有人可以解释这个编程问题吗?

1 个答案:

答案 0 :(得分:1)

根据How would I stop a while loop after n amount of time?上的讨论,特别是安东尼的评论,我会回答你的问题:https://stackoverflow.com/a/44723559/8763097

while True:循环往往会占用CPU进程,我认为这被称为:Busy Waiting

  

繁忙等待,忙碌循环或旋转是一种技术   进程重复检查以查看条件是否为真,例如   键盘输入或锁定是否可用。

     

使用延迟可以减少繁忙等待本身的浪费   在大多数操作系统中找到的功能(例如,sleep())。这就是一个   线程在指定时间内休眠,在此期间线程会   浪费没有CPU时间。如果循环正在检查一些简单的东西那么它   将花费大部分时间睡着,浪费很少的CPU   时间。

因此,你的while循环花费了大量时间来检查len(key_press)的if语句值一遍又一遍。添加sleep()例程将允许While循环暂停,从而可以进行其他过程。

这可能是您报告时间函数不一致的原因 - 函数.core.getTime()不是核心python函数。它是心理包的核心部分,它看起来不像是一个处理时钟......它看起来像一个基本的时钟计时器。因此,定时器可能受到While循环CPU占用的影响。但是,如果不了解您的包装时钟处理,这只是猜测。

也许为了避免这个问题,考虑将time.perf_counter()与睡眠功能一起使用,因为这将包括计数内的任何sleep()时间。

编辑1:也许一个解决方案是使用MS VC ++运行时库,它在Python的核心内部。

import msvcrt
import time

print("GO")
start = time.perf_counter()
while True:
    if msvcrt.kbhit():
        end = time.perf_counter()
        print(end-start)
        break

库应该能够处理命令以等待键盘按下,然后再转到循环中的下一步。它解决了这个问题吗?不完全的。问题真的可以解决吗?我不确定......