【发布时间】:2020-12-13 10:53:11
【问题描述】:
我有一个 python 程序,它从串行端口读取数据,访问寄存器然后将数据写入 CSV。我想以 100Hz 的设定频率对 csv 执行写入操作。下面是与尝试限制写入 csv 的时间相关的示例代码。为简单起见,它只会打印到控制台而不是写入 csv。
import datetime
from datetime import timezone
import time
FREQ = 5
CYCLETIME = 1/FREQ
def main():
while(1):
### Code that will read message bytes from a port
# Time start for Hz
start = time.monotonic()
delta = time.monotonic() - start
if delta < CYCLETIME:
time.sleep(CYCLETIME - delta)
# in the full program we write to a csv but in this simple program we will just print it
milliseconds_since_epoch = datetime.datetime.now(timezone.utc)
print(milliseconds_since_epoch)
if __name__ == "__main__":
main()
2020-08-24 18:57:15.572637+00:00
2020-08-24 18:57:15.773183+00:00
2020-08-24 18:57:15.973637+00:00
2020-08-24 18:57:16.174117+00:00
2020-08-24 18:57:16.374569+00:00
2020-08-24 18:57:16.575058+00:00
2020-08-24 18:57:16.775581+00:00
2020-08-24 18:57:16.976119+00:00
2020-08-24 18:57:17.176627+00:00
2020-08-24 18:57:17.377103+00:00
2020-08-24 18:57:17.577556+00:00
5Hz 的输出似乎一致,但如果我将其更改为 100Hz,它似乎不一致。听起来这可能是与 time.monotonic 相关的时间精度漂移。这是一个好方法吗? time.montonic 合适吗?
我对 pythons 线程库的了解有限,但在不久的将来,我计划为每个任务创建 2 个子线程。一个不断从串行读取,另一个将写入(或者在我们的例子中,每 100Hz 打印到控制台)。
编辑: 我采用了下面的解决方案并对其进行了修改。最初的解决方案似乎只打印一次。这是我的新尝试:
import datetime
from datetime import timezone
import time
FREQ = 5
CYCLETIME = 1/FREQ
def main():
t0 = time.perf_counter() # Time ref point in ms
time_counter = t0 # Will be incremented with CYCLETIME for each iteration
while 1:
### Code that will read message bytes from a port
now = time.perf_counter()
elapsed_time = now - time_counter
if elapsed_time < CYCLETIME:
target_time = CYCLETIME - elapsed_time
time.sleep(target_time)
# In the full program we write to a csv but in this simple program we will just print it
milliseconds_since_epoch = datetime.datetime.now(timezone.utc)
print(milliseconds_since_epoch)
time_counter += CYCLETIME
if __name__ == "__main__":
main()
输出:
我使用 matplot lib 来确定创建此输出的频率。我取当前值和前一个值的滚动窗口差,并从频率 = 1/(时间差)开始反转它。
【问题讨论】:
标签: python-3.x multithreading time