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

Python如何不阻塞主循环持续写入文件并实现优雅退出

解决方案

你原始代码的核心问题是直接调用WriteToFile()会阻塞主进程,导致后续的测量循环完全无法执行,我们通过多线程+停止标志位的方案就能满足你的需求,该方案兼容你当前使用的Python 3.5.3版本,无需升级。

核心修改思路

  • 引入threading模块将WriteToFile放到独立子线程运行,不阻塞主测量流程
  • 新增全局停止标志位控制WriteToFile的循环,避免暴力杀死线程导致文件未正常关闭
  • 拆分10秒等待为小时间片轮询,保证停止命令可以快速响应
  • 文件写入改用with上下文管理器,自动处理文件关闭,避免资源泄漏

修改后完整代码

from datetime import datetime
import os
import time
import sys
import random
import threading

M_Max = 2000
M_Array = [740] 
D_Array = [5, 10, 20, 100, 150, 200, 400,600, 740]  

M=random.random()*20000
D=random.random()*7500

# 停止WriteToFile的标志位
stop_write_flag = False
# 存储写文件子线程的对象
write_thread = None

# write data to a file every ten seconds  
def WriteToFile():  
    global stop_write_flag
    while not stop_write_flag:
        # 使用with上下文管理器,自动关闭文件,即使写入出错也不会漏关
        with open("FastFile.txt", "a") as h:
            current_time_t=datetime.now().strftime("%d.%m.%y %H:%M:%S")
            p = random.random()*1000
            c = random.random()*100
            
            print("Fast_Time :", '{} {:9.0f} {:9.0f} {:9.3f} {:9.1f}  '.format(current_time_t, M, D, p, c))
            h.write("\n %s , %s , %s , %s, %s  " % (
                current_time_t, 
                str('{:.1f}'.format(M)), 
                str('{:.1f}'.format(D)), 
                str('{:.3f}'.format(p)), 
                str('{:.2f}'.format(c))
            ))
        # 拆分10秒等待为20次0.5秒等待,每次检查停止标志,响应更快
        wait_cnt = 0
        while wait_cnt < 20 and not stop_write_flag:
            time.sleep(0.5)
            wait_cnt += 1
    print("WriteToFile已正常退出,FastFile.txt已关闭")

def CleanUp():
    global stop_write_flag, write_thread
    print("Cleaning up,等待2分钟后停止写文件")
    # 先等2分钟
    time.sleep(120)
    # 设置停止标志
    stop_write_flag = True
    # 等待子线程完全退出,确保文件操作完成
    write_thread.join()
    print("Done")
    sys.exit()

def main():
    global M, D, write_thread
    # 启动写文件子线程
    write_thread = threading.Thread(target=WriteToFile, daemon=True)
    write_thread.start()

    print("Starting measurement")
    time.sleep(3)
    
    for M in M_Array:
        for D in D_Array:  
            p = random.random()*1000
            c = random.random()*100
            # 同样用with上下文管理器处理SlowFile的写入
            with open("SlowFile.txt", "a") as g:
                current_time_t = datetime.now().strftime("%d.%m.%y %H:%M:%S")
                print("Main_Time :", '{} {:9.0f} {:9.0f} {:9.3f} {:9.1f}  '.format(current_time_t, M, D, p, c))
                g.write("\n %s , %s , %s , %s, %s  " % (
                    current_time_t, 
                    str('{:.1f}'.format(M)), 
                    str('{:.1f}'.format(D)), 
                    str('{:.3f}'.format(p)), 
                    str('{:.2f}'.format(c))
                ))

    CleanUp()

if __name__ == "__main__":
    main()

关键说明

  • 标志位控制退出可以保证WriteToFile完成当前正在执行的写入操作后再退出,不会出现半行数据残留或者文件未关闭的问题
  • 子线程读取全局变量M、D属于简单原子操作,无需额外加锁就可以保证数据一致性,符合你的使用场景
  • 如果你需要提前终止程序,只要触发stop_write_flag = True再调用write_thread.join()就可以实现优雅退出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 06:09:03