79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
#!/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()
|