Files
iOSAI/Utils/ThreadManager.py

80 lines
2.8 KiB
Python
Raw Normal View History

2025-09-22 19:10:58 +08:00
import ctypes
2025-09-17 22:23:57 +08:00
import threading
2025-09-19 19:39:32 +08:00
from typing import Dict, Tuple, List
2025-09-22 19:10:58 +08:00
2025-08-06 22:11:33 +08:00
from Utils.LogManager import LogManager
2025-09-22 19:10:58 +08:00
def _async_raise(tid: int, exc_type=KeyboardInterrupt):
"""向指定线程抛异常,强制跳出"""
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exc_type))
if res == 0:
raise ValueError("线程不存在")
elif res > 1:
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), 0)
2025-09-17 22:23:57 +08:00
class ThreadManager:
2025-09-18 20:09:52 +08:00
_tasks: Dict[str, Dict] = {}
2025-09-17 22:23:57 +08:00
_lock = threading.Lock()
2025-08-06 22:11:33 +08:00
@classmethod
2025-09-18 20:09:52 +08:00
def add(cls, udid: str, thread: threading.Thread, event: threading.Event) -> Tuple[int, str]:
2025-09-22 19:10:58 +08:00
LogManager.method_info(f"准备创建任务:{udid}", "task")
2025-10-22 18:24:43 +08:00
LogManager.method_info("创建线程成功", "监控消息")
2025-09-18 20:09:52 +08:00
with cls._lock:
2025-09-22 19:10:58 +08:00
# 判断当前设备是否有任务
if cls._tasks.get(udid, None) is not None:
return 1001, "当前设备已存在任务"
thread.start()
print(thread.ident)
2025-09-18 20:09:52 +08:00
cls._tasks[udid] = {
2025-09-22 19:10:58 +08:00
"id": thread.ident,
2025-09-18 20:09:52 +08:00
"thread": thread,
2025-09-22 19:10:58 +08:00
"event": event
2025-09-18 20:09:52 +08:00
}
2025-09-22 19:10:58 +08:00
return 200, "创建成功"
2025-08-06 22:11:33 +08:00
@classmethod
2025-09-18 20:09:52 +08:00
def stop(cls, udid: str) -> Tuple[int, str]:
2025-09-22 19:10:58 +08:00
try:
print(cls._tasks)
obj = cls._tasks.get(udid, None)
obj["event"].set()
r = cls._kill_thread(obj.get("id"))
if r:
cls._tasks.pop(udid, None)
else:
print("好像有问题")
except Exception as e:
print(e)
return 200, "操作成功"
2025-09-17 22:23:57 +08:00
2025-09-19 19:39:32 +08:00
@classmethod
2025-09-22 19:10:58 +08:00
def batch_stop(cls, ids: List[str]) -> Tuple[int, str]:
try:
for udid in ids:
cls.stop(udid)
except Exception as e:
print(e)
return 200, "停止成功."
2025-09-19 19:39:32 +08:00
2025-09-18 20:09:52 +08:00
@classmethod
2025-09-22 19:10:58 +08:00
def _kill_thread(cls, tid: int) -> bool:
"""向原生线程 ID 抛 KeyboardInterrupt强制跳出"""
2025-09-28 20:42:01 +08:00
try:
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
ctypes.py_object(KeyboardInterrupt))
# LogManager.method_info(f"向原生线程 {tid} 抛 KeyboardInterrupt强制跳出", "task")
if res == 0: # 线程已不存在
print("线程不存在")
return False
if res > 1: # 命中多个线程,重置
print("命中了多个线程")
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), 0)
LogManager.method_info("杀死线程创建成功", "监控消息")
print("杀死线程成功")
return True
except Exception as e:
print("杀死线程出现问题 错误的原因:",e)