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

Python脚本执行exit()后无法退出,如何排查故障原因?

问题:Python脚本执行exit()后无法退出,控制台完全挂起

现象

脚本执行到exit()语句时卡住,控制台已输出所有设备关闭的日志,但无法回到命令提示符,甚至Ctrl-C和Ctrl-Break都无效:

Closing connections to test equipment.
motion device connection closed.
sampling device connection closed.
signal generator connection closed.

调用代码:

CloseEquipmentAndExit(equipment = [motion_device, sampling_device, gen], test_config = _test_settings, timestamps = script_timestamps)

对应的函数定义:

def CloseEquipmentAndExit(equipment: list, test_config: dict, timestamps = None):
    sys.stdout.write('Closing connections to test equipment.\r\n')
    for item in equipment:
        try:
            if type(item) == motion_device:
                item.Move(test_config['Robot']['park'])
            item.Close()
            sys.stdout.write(f'{item.NAME} connection closed.\r\n')
            if not timestamps is None: timestamps.add(f"{item.NAME} Robot Close")
        except:
            pass
    exit()

排查方案

  • 替换exit()为sys.exit()并捕获退出异常
    原生exit()是交互式环境的函数,脚本中建议用sys.exit(),同时捕获退出时的异常,看是否有隐藏错误阻止进程终止:

    import sys
    # ... 其他代码 ...
    try:
        sys.exit(0)
    except Exception as e:
        print(f"Exit failed: {str(e)}")
        import traceback
        traceback.print_exc()
    
  • 检查后台线程是否未终止
    如果设备操作启动了非守护线程(默认daemon=False),这些线程会阻止进程退出。在exit()前添加线程枚举代码,查看活跃线程状态:

    import threading
    # 在exit()前插入
    print("Active threads:")
    for thread in threading.enumerate():
        print(f"  Name: {thread.name}, Daemon: {thread.daemon}, Alive: {thread.is_alive()}")
    

    若发现非守护线程存活,要么在创建线程时设为daemon=True,要么在退出前主动终止这些线程。

  • 验证Close()方法是否真正执行完成
    日志打印不代表item.Close()底层操作已完成,可能存在阻塞未返回。给每个Close()添加时间戳日志,同时修改异常捕获逻辑,避免掩盖错误:

    import time
    # 修改try-except块
    try:
        if type(item) == motion_device:
            item.Move(test_config['Robot']['park'])
        item.Close()
        print(f"{item.NAME} connection closed at {time.ctime()}")
        if not timestamps is None: timestamps.add(f"{item.NAME} Robot Close")
    except Exception as e:
        print(f"Error closing {item.NAME}: {str(e)}")
        import traceback
        traceback.print_exc()
    
  • 排查timestamps对象的阻塞问题
    注释掉timestamps.add()这行代码,测试是否能正常退出。如果可以,说明自定义的timestamps对象内部存在锁、IO阻塞等问题。

  • 用系统工具定位阻塞点
    Windows下用Process Explorer查看进程的线程调用栈;Linux/macOS下用strace -p <进程ID>跟踪系统调用,看进程卡在哪个系统操作上,精准定位阻塞原因。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:00:31