#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 测试退出时所有线程是否正确关闭 """ import threading import time def check_threads(): """检查当前运行的线程""" print("=" * 60) print("当前活动线程列表:") print("=" * 60) threads = threading.enumerate() print(f"总计线程数: {len(threads)}\n") for thread in threads: print(f"线程名称: {thread.name}") print(f" - 是否 Daemon: {thread.daemon}") print(f" - 是否存活: {thread.is_alive()}") print(f" - 线程 ID: {thread.ident}") print() # 检查是否有非 daemon 线程(除了主线程) non_daemon_threads = [t for t in threads if not t.daemon and t.name != 'MainThread'] print("=" * 60) if non_daemon_threads: print(f"⚠️ 警告: 发现 {len(non_daemon_threads)} 个非 daemon 线程(可能导致程序无法退出):") for thread in non_daemon_threads: print(f" - {thread.name} (ID: {thread.ident})") else: print("✓ 所有非主线程都是 daemon 线程,程序可以正常退出") print("=" * 60) return threads def check_for_polling_threads(): """检查是否有轮询相关的线程还在运行""" print("\n" + "=" * 60) print("检查轮询相关线程:") print("=" * 60) threads = threading.enumerate() polling_threads = [] keywords = ['poll', 'timer', 'modbus', 'plc', 'mock'] for thread in threads: thread_name_lower = thread.name.lower() if any(keyword in thread_name_lower for keyword in keywords): polling_threads.append(thread) print(f"⚠️ 发现轮询线程: {thread.name}") print(f" - Daemon: {thread.daemon}") print(f" - 存活: {thread.is_alive()}") if not polling_threads: print("✓ 未发现轮询相关线程") print("=" * 60) return polling_threads if __name__ == "__main__": print("\n程序启动后等待 2 秒...") time.sleep(2) print("\n第一次检查 (启动后):") check_threads() check_for_polling_threads() print("\n\n提示: 关闭 UI 窗口后再次检查...") print("等待 5 秒后再次检查...") time.sleep(5) print("\n第二次检查 (5秒后):") check_threads() check_for_polling_threads()