python - 多线程 Python 程序中的计时器漂移
问题描述
我目前正在为一个项目开发数据记录器。数据记录器应从车载访问平台上的两个不同 CAN 总线系统读取数据,解码原始数据并将其定期存储在 json 文件中,该文件将在设备关闭之前上传到 blob 存储。我正在使用基于树莓派的硬件并在 Python 3.7 中对其进行编程。除了定期存储数据外,一切正常。在 json 文件中创建和存储数据开始良好,并在一分钟后以 100 毫秒的步长完成,您开始看到两个数据点之间的时间漂移。如果您将代码运行数小时,则数据点之间的时间会长达数分钟。
我知道 Linux 不是 RTOS,但应该可以以 100 毫秒的步长保存数据。那么我的方法是错误的吗?
我尝试使用 threading.Event 而不是睡眠,我还尝试将它作为多个进程而不是线程运行。
这是我遇到问题的函数的代码:
def create_json_file():
global FILE_INITIALIZED
global FILE_NAME
once = bool
try:
while not stop_create.is_set():
if not store_data:
next_call = time.time()
if store_data == True:
if not once:
next_call = time.time()
once = True
# Calculate the offset taking into account daylight saving time
utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone
utc_offset = datetime.timedelta(seconds=-utc_offset_sec)
timestamp = datetime.datetime.now().replace(tzinfo=datetime.timezone(offset=utc_offset)).isoformat()
tmp_json_dict = {}
tmp_json_dict['deviceId'] = DEVICE_ID
tmp_json_dict['timestamp'] = timestamp
tmp_json_dict.update(processed_data)
if FILE_INITIALIZED == False:
first_json_dict = []
first_json_dict.append(tmp_json_dict)
FILE_NAME = './storage/' + DEVICE_ID + datetime.datetime.now().strftime("_%Y%m%d_%H%M.json")
#/home/pi/Test
if FILE_INITIALIZED == False:
with open(FILE_NAME,"w+") as outputfile:
json.dump(first_json_dict,outputfile,indent=4,sort_keys=False)
FILE_INITIALIZED = True
first_json_dict.clear()
else:
with open(FILE_NAME, "r+") as file:
file_data = json.load(file)
file_data.append(tmp_json_dict)
file.seek(0)
json.dump(file_data, file, indent=4)
next_call = next_call + INTERVAL_TIME
time.sleep(abs(next_call - time.time()))
except Exception as err:
logging.exception(err)
if not stop_create.is_set():
# Only log exception if we were not going to stop the thread
# When quitting, the main thread calls close() on the serial device
# and read() may throw an exception. We don't want to display it as
# we're stopping the script anyway
global thread_exception_file
thread_exception_file = sys.exc_info()
这是一段时间后有漂移的输出:
[
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:24:13.480148+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:24:13.580144+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:24:13.679995+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:24:13.780075+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:24:13.880101+01:00"
},
...
...
...
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:25:20.078147+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:25:20.316632+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:25:20.556145+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:25:20.797479+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:25:21.041794+01:00"
},
{
"deviceId": "Prototype_FieldTest_P300KS_Facelift",
"timestamp": "2020-11-28T22:25:21.288214+01:00"
}
]
解决方案
推荐阅读
- c# - c#动态sql循环通过服务器命令或linq
- python - Jupyter Notebook 加载 .ipynb 文件时出错
- regex - RegEx - 删除特定模式(例如前缀和后缀)的更有效方法
- android - 致命异常:java.lang.IllegalStateException:失败保存状态:活动片段已从 FragmentManager 中删除
- mysql - mysql 查询不会为每个月的每一天提供 0 值。只会返回大于 0 的值
- python - 模块“numpy”没有属性“testing”
- mongodb - Mongodb搜索逗号分隔字符串和变音符号Insentive搜索
- javascript - 新的 Array() 与 Array() JavaScript
- http - 如何计算nginx中的平均处理时间
- python - Django导航栏链接在帖子中消失