Python while循环内的准确睡眠/延迟 [英] Accurate sleep/delay within Python while loop

查看:465
本文介绍了Python while循环内的准确睡眠/延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a while True loop which sends variables to an external function, and then uses the returned values. This send/receive process has a user-configurable frequency, which is saved and read from an external .ini configuration file.

我尝试过time.sleep(1/Frequency),但是鉴于其他地方使用的线程数,我对精度不满意.例如. 60Hz的频率(0.0166667的周期)给出的实际" time.sleep()周期约为0.0311.

I've tried time.sleep(1 / Frequency), but am not satisfied with the accuracy, given the number of threads being used elsewhere. E.g. a frequency of 60Hz (period of 0.0166667) is giving an 'actual' time.sleep() period of ~0.0311.

我更喜欢使用附加的while循环,该循环将当前时间与开始时间和时间段进行比较,如下所示:

My preference would be to use an additional while loop, which compares the current time to the start time plus the period, as follows:

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

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

This would fit into the end of my while True function as follows:

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循环的添加使函数仅执行一次.如何使以上功能正常运行?这是在非实时操作系统上精确"控制频率的最佳方法吗?我应该为此特定组件使用线程吗?我正在Windows 7(64位)和Ubuntu(64位)上测试此功能.

I'm missing something, as the addition of the while loop causes the function to execute once only. How can I get the above to function correctly? Is this the best approach to 'accurate' frequency control on a non-real time operating system? Should I be using threading for this particular component? I'm testing this function on both Windows 7 (64-bit) and Ubuntu (64-bit).

推荐答案

如果我正确理解了您的问题,则希望以给定的频率执行ExternalFunction.main.问题是ExternalFunction.main本身的执行需要一些时间.如果您不需要非常高的精度-似乎您不需要-我的建议是这样做.

If I understood your question correctly, you want to execute ExternalFunction.main at a given frequency. The problem is that the execution of ExternalFunction.main itself takes some time. If you don't need very fine precision -- it seems that you don't -- my suggestion is doing something like this.

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循环执行得更频繁.

You may tune the precision to your needs. Greater precision (smaller number) will make the inner while loop execute more often.

当不使用线程时,这会获得不错的结果.但是,使用Python线程时,GIL(全局解释器锁定)可确保一次仅运行一个线程.如果您有大量线程,则可能是因为程序花费了太多时间才能返回到主线程.增加线程之间Python更改的频率可能会给您带来更准确的延迟.

This achieves decent results when not using threads. However, when using Python threads, the GIL (Global Interpreter Lock) makes sure only one thread runs at a time. If you have a huge number of threads it may be that it is taking way too much time for the program to go back to your main thread. Increasing the frequency Python changes between threads may give you more accurate delays.

将此添加到代码的开头,以增加线程切换频率.

Add this to the beginning of your code to increase the thread switching frequency.

import sys
sys.setcheckinterval(1)

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

1 is the number of instructions executed on each thread before switching (the default is 100), a larger number improves performance but will increase the threading switching time.

这篇关于Python while循环内的准确睡眠/延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆