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

如何在RPI3网络监控脚本中安全终止无预设退出条件的无限循环?

解决树莓派3网络监控脚本的XLSX保存问题

嘿,这个问题我之前在树莓派上做监控脚本时也碰到过!xlsxwriter的“只能新建写入、无法编辑现有文件”特性加上无限循环的退出问题,确实让人头疼,不过有几个靠谱的解决方案,我给你梳理一下:

方案1:用信号处理捕获终止信号,触发文件保存

这是最直接的解决办法——给脚本加上信号监听,当你按下Ctrl+C或者系统发送终止信号时,自动执行workbook.close()保存文件,而不是直接强制终止。

代码示例:

import signal
import xlsxwriter
import time

# 初始化Excel工作簿和工作表(循环外只做一次)
workbook = xlsxwriter.Workbook('network_speed.xlsx')
worksheet = workbook.add_worksheet()
current_row = 0

# 写入表头
worksheet.write(current_row, 0, '时间')
worksheet.write(current_row, 1, '下载速度')
worksheet.write(current_row, 2, '上传速度')
current_row += 1

# 定义退出处理函数
def graceful_exit(signum, frame):
    print("\n收到终止信号,正在保存数据...")
    workbook.close()
    print("Excel文件已保存,程序正常退出")
    exit(0)

# 注册信号监听:捕获Ctrl+C(SIGINT)和系统终止信号(SIGTERM)
signal.signal(signal.SIGINT, graceful_exit)
signal.signal(signal.SIGTERM, graceful_exit)

# 无限循环的监控逻辑
while True:
    # --------------------------
    # 这里替换成你的网络速度获取代码
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    download = "120Mbps"  # 实际获取的下载速度
    upload = "60Mbps"     # 实际获取的上传速度
    # --------------------------

    # 写入当前数据到内存中的工作表
    worksheet.write(current_row, 0, now)
    worksheet.write(current_row, 1, download)
    worksheet.write(current_row, 2, upload)
    current_row += 1

    time.sleep(5)  # 每隔5秒监控一次

优点:

  • 逻辑简单,不需要改原有监控流程
  • xlsxwriter的内存缓存机制能保证写入效率,只有在退出时一次性写入磁盘

注意:

如果程序因为意外崩溃(比如断电),内存中未保存的数据还是会丢失,适合对数据完整性要求不是极高的场景。


方案2:用CSV临时存储+OpenPyXL转存Excel

如果担心意外崩溃丢数据,可以先用CSV文件实时追加数据(CSV支持追加写入),再定期用OpenPyXL把CSV数据同步到Excel文件——OpenPyXL支持编辑现有Excel文件,完美弥补xlsxwriter的短板。

代码示例:

import csv
import time
from openpyxl import Workbook, load_workbook

# 定义CSV转Excel的函数
def sync_csv_to_excel(csv_path, excel_path):
    # 读取CSV所有数据
    with open(csv_path, 'r', newline='', encoding='utf-8') as f:
        csv_reader = csv.reader(f)
        all_data = list(csv_reader)
    
    # 写入/更新Excel文件
    try:
        # 如果Excel已存在,加载后覆盖数据(保留表头)
        wb = load_workbook(excel_path)
        ws = wb.active
        # 清空原有数据(从第2行开始)
        for row in ws.iter_rows(min_row=2):
            for cell in row:
                cell.value = None
        # 写入新数据
        for row_idx, row_data in enumerate(all_data, 1):
            for col_idx, value in enumerate(row_data, 1):
                ws.cell(row=row_idx, column=col_idx, value=value)
    except FileNotFoundError:
        # 如果Excel不存在,新建并写入所有数据
        wb = Workbook()
        ws = wb.active
        for row_data in all_data:
            ws.append(row_data)
    
    wb.save(excel_path)
    wb.close()

# 初始化CSV文件(写入表头)
csv_file = 'network_speed_temp.csv'
with open(csv_file, 'w', newline='', encoding='utf-8') as f:
    csv_writer = csv.writer(f)
    csv_writer.writerow(['时间', '下载速度', '上传速度'])

loop_counter = 0
while True:
    # --------------------------
    # 替换成你的网络速度获取逻辑
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    download = "120Mbps"
    upload = "60Mbps"
    # --------------------------

    # 追加数据到CSV(实时写入磁盘,不会丢)
    with open(csv_file, 'a', newline='', encoding='utf-8') as f:
        csv_writer = csv.writer(f)
        csv_writer.writerow([now, download, upload])
    
    # 每10次循环同步一次到Excel(可根据需求调整频率)
    loop_counter += 1
    if loop_counter % 10 == 0:
        sync_csv_to_excel(csv_file, 'network_speed.xlsx')
        print(f"{now}:已同步数据到Excel")
    
    time.sleep(5)

优点:

  • 即使程序崩溃,CSV里的所有数据都不会丢失
  • Excel文件可以随时查看最新数据,不需要等程序退出

注意:

同步频率不要太高(比如不要每次循环都同步),避免频繁IO操作占用树莓派资源。


方案3:直接用OpenPyXL实时写入Excel

如果不想用CSV中转,也可以直接用OpenPyXL每次循环打开Excel文件追加数据,然后保存关闭——虽然每次循环都有IO操作,但树莓派3的性能完全能应付。

代码示例:

import time
import signal
from openpyxl import Workbook, load_workbook

excel_file = 'network_speed.xlsx'

# 初始化Excel文件和表头
try:
    wb = load_workbook(excel_file)
    ws = wb.active
    # 检查是否存在表头,没有就添加
    if ws.cell(row=1, column=1).value != '时间':
        ws.append(['时间', '下载速度', '上传速度'])
except FileNotFoundError:
    wb = Workbook()
    ws = wb.active
    ws.append(['时间', '下载速度', '上传速度'])
wb.save(excel_file)
wb.close()

# 定义退出处理函数
def graceful_exit(signum, frame):
    print("\n程序正常退出")
    exit(0)

signal.signal(signal.SIGINT, graceful_exit)
signal.signal(signal.SIGTERM, graceful_exit)

while True:
    # --------------------------
    # 替换成你的网络速度获取逻辑
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    download = "120Mbps"
    upload = "60Mbps"
    # --------------------------

    # 打开Excel追加数据
    wb = load_workbook(excel_file)
    ws = wb.active
    ws.append([now, download, upload])
    wb.save(excel_file)
    wb.close()  # 显式关闭释放资源

    time.sleep(5)

优点:

  • 数据实时保存到Excel,随时可以查看
  • 不需要额外维护CSV文件

注意:

每次循环的IO操作会比内存缓存慢一点,但对于5秒一次的监控来说完全可以忽略。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:39:58