You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Modbus高频数据记录脚本异常:长时间运行后停止采集

高频Modbus数据采集脚本长时间运行停止问题的排查与解决

针对你遇到的高频采集(6-9ms/次)脚本长时间运行后静默停止、CSV数据不足甚至为空的问题,结合你的环境(Windows10 + Python3.9 + pymodbus/pandas/matplotlib),可以从以下几个方向排查解决:

一、内存溢出优化

持续向单个pandas DataFrame追加数据会导致内存占用线性增长,长时间运行后可能触发系统隐性内存回收或进程终止,且无报错提示。

  • 改用分块写入CSV:每采集固定条数(比如1000条)就将临时数据写入CSV,随后清空临时DataFrame释放内存。第一次写入时带表头,后续追加跳过表头:
    import pandas as pd
    import os
    
    csv_path = "data.csv"
    temp_data = []
    batch_size = 1000
    
    # 采集到单条数据后加入临时列表
    temp_data.append({"RPM": rpm_val, "扭矩": torque_val, ...})
    
    # 达到批次大小则写入
    if len(temp_data) >= batch_size:
        df = pd.DataFrame(temp_data)
        df.to_csv(csv_path, mode='a', header=not os.path.exists(csv_path), index=False)
        temp_data.clear()  # 清空临时数据
    
  • 每次清空临时数据后,手动触发垃圾回收:
    import gc
    gc.collect()
    

二、Modbus连接稳定性修复

高频通信下,连接可能隐性断开或请求超时,pymodbus默认逻辑不会主动报错,导致采集静默停止。

  • 每次采集前检查连接状态,断开则自动重连:
    from pymodbus.client import ModbusTcpClient
    
    client = ModbusTcpClient("plc_ip", port=502)
    
    def ensure_connection():
        if not client.is_socket_open():
            try:
                client.connect()
                print("重新建立Modbus连接")
            except Exception as e:
                print(f"重连失败: {str(e)}")
    
  • 给Modbus请求设置匹配采集频率的超时时间,避免请求挂起阻塞主线程:
    # 超时设为10ms,略高于单次采集耗时
    response = client.read_holding_registers(start_addr, register_count, timeout=0.01)
    
  • 捕获Modbus通信异常,避免静默失败:
    from pymodbus.exceptions import ModbusIOException
    
    try:
        response = client.read_holding_registers(...)
        if response.isError():
            print(f"Modbus响应错误: {response}")
            ensure_connection()
    except ModbusIOException as e:
        print(f"通信异常: {str(e)}")
        ensure_connection()
    

三、Windows系统进程限制排查

Windows对后台进程的资源调度可能存在隐性限制,导致高频任务被系统终止但无控制台报错。

  • 将脚本进程优先级设为高,避免被系统调度压制:
    import psutil
    
    proc = psutil.Process()
    proc.nice(psutil.HIGH_PRIORITY_CLASS)  # Windows环境下生效
    
  • 打开Windows事件查看器(eventvwr.msc),在「Windows日志-应用程序」中查找脚本进程的终止日志,确认是否被系统强制结束。

四、CSV写入可靠性提升

写入CSV时的缓冲区未刷新、磁盘异常或文件被占用,可能导致数据丢失或仅存表头。

  • 写入时强制刷新磁盘缓冲区,避免数据停留在内存中:
    import os
    
    with open(csv_path, 'a', newline='') as f:
        df.to_csv(f, header=not os.path.exists(csv_path), index=False)
        f.flush()
        os.fsync(f.fileno())  # 强制将缓冲区数据写入磁盘
    
  • 使用临时文件写入,完成后替换目标文件,避免中途崩溃导致文件损坏:
    import shutil
    
    temp_csv = "temp_data.csv"
    # 先写入临时文件
    df.to_csv(temp_csv, mode='a', header=not os.path.exists(temp_csv), index=False)
    # 替换目标文件
    shutil.move(temp_csv, csv_path)
    

五、主线程阻塞排查

若脚本包含matplotlib实时绘图逻辑,高频采集时绘图操作可能阻塞主线程,导致采集停止。

  • 将绘图逻辑放到独立线程中,通过队列传递数据,不影响采集主线程:
    import threading
    import queue
    
    data_queue = queue.Queue()
    
    def plot_task():
        while True:
            if not data_queue.empty():
                data = data_queue.get()
                # 执行绘图逻辑,比如更新图表
                # ...
    
    # 启动绘图线程(设为守护线程,随主线程退出)
    plot_thread = threading.Thread(target=plot_task, daemon=True)
    plot_thread.start()
    
    # 采集到数据后放入队列
    data_queue.put(new_data_dict)
    

内容的提问来源于stack exchange,提问作者Arie3s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:17:13