循环中

时间:2017-05-03 23:29:59

标签: python python-3.x sleep frequency

我有一个True循环,它将变量发送到外部函数,然后使用返回的值。此发送/接收过程具有用户可配置的频率,可以从外部.ini配置文件中保存和读取。

我已经尝试过time.sleep(1 /频率),但考虑到其他地方使用的线程数,我对准确性不满意。例如。频率为60Hz(周期为0.0166667)正在给出一个实际的' time.sleep()周期~0.0311。

我的偏好是使用额外的while循环,将当前时间与开始时间加上句点进行比较,如下所示:

EndTime = time.time() + (1 / Frequency)
while time.time() - EndTime < 0:
    sleep(0)

这将适合我的True函数的结尾,如下所示:

while True:
    A = random.randint(0, 5)
    B = random.randint(0, 10)
    C = random.randint(0, 20)

    Values = ExternalFunction.main(Variable_A = A, Variable_B = B, Variable_C = C)

    Return_A = Values['A_Out']
    Return_B = Values['B_Out']
    Return_C = Values['C_Out']

    #Updated other functions with Return_A, Return_B and Return_C

    EndTime = time.time() + (1 / Frequency)
    while time.time() - EndTime < 0:
        time.sleep(0)

我遗漏了一些东西,因为添加while循环会导致函数只执行一次。如何让上述功能正常运行?这是准确&#39;的最佳方法吗?非实时操作系统的频率控制?我应该为这个特定组件使用线程吗?我在Windows 7(64位)和Ubuntu(64位)上测试此功能。

3 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你想以给定的频率执行ExternalFunction.main。问题是ExternalFunction.main本身的执行需要一些时间。如果你不需要非常精确的 - 似乎你没有 - 我的建议是做这样的事情。

import time

frequency = 1  # Hz
period = 1.0/frequency

while True:
    time_before = time.time()
    [...]
    ExternalFunction.main([...])
    [...]
    while (time.time() - time_before) < period:
        time.sleep(0.001)  # precision here

您可以根据需要调整精度。更高的精度(更小的数字)将使内部while循环更频繁地执行。

这在不使用线程时获得了不错的结果。但是,使用Python线程时,GIL(全局解释器锁)确保一次只运行一个线程。如果你有大量的线程,那么程序可能会花费太多时间返回主线程。增加线程之间Python更改的频率可能会给您更准确的延迟。

将其添加到代码的开头以增加线程切换频率。

import sys
sys.setcheckinterval(1)

1是在切换之前在每个线程上执行的指令数(默认值为100),较大的数字会提高性能但会增加线程切换时间。

答案 1 :(得分:0)

您可以尝试python-pause

  

暂停到unix时间,精确到毫秒:

import pause
pause.until(1370640569.7747359)
     

暂停使用日期时间:

import pause, datetime
dt = datetime.datetime(2013, 6, 2, 14, 36, 34, 383752)
pause.until(dt)

您可以使用它:

freqHz=60.0
td=datetime.timedelta(seconds=1/freqHz)
dt=datetime.now()

while true:
  #Your code here
  dt+=td
  pause.until(dt)

答案 2 :(得分:0)

准确延迟的另一个解决方案是从模块时间使用perf_counter()函数。在windows中特别有用,因为time.sleep在几毫秒内不准确。请参阅下面的示例,其中函数accurate_delay以毫秒为单位创建延迟。

headers = {
            "Host": "login.flash.co.za",
            "Connection": "keep-alive",
            "Origin": "https://login.flash.co.za",
            "Upgrade-Insecure-Requests": "1",
            "Content-Type": "application/x-www-form-urlencoded",
            "User-Agent": "Mozilla/5.0 (Windows NT x.y; rv:10.0) Gecko/20100101 Firefox/10.0",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
            "Referer": "https://login.flash.co.za/apex/f?p=pwfone:login",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "en-US,en;q=0.9",
}