80 lines
2.8 KiB
Python
80 lines
2.8 KiB
Python
import ctypes
|
||
import threading
|
||
from typing import Dict, Tuple, List
|
||
|
||
from Utils.LogManager import LogManager
|
||
|
||
|
||
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)
|
||
|
||
class ThreadManager:
|
||
_tasks: Dict[str, Dict] = {}
|
||
_lock = threading.Lock()
|
||
|
||
@classmethod
|
||
def add(cls, udid: str, thread: threading.Thread, event: threading.Event) -> Tuple[int, str]:
|
||
LogManager.method_info(f"准备创建任务:{udid}", "task")
|
||
LogManager.method_info("创建线程成功","监控消息")
|
||
with cls._lock:
|
||
# 判断当前设备是否有任务
|
||
if cls._tasks.get(udid, None) is not None:
|
||
return 1001, "当前设备已存在任务"
|
||
thread.start()
|
||
print(thread.ident)
|
||
|
||
cls._tasks[udid] = {
|
||
"id": thread.ident,
|
||
"thread": thread,
|
||
"event": event
|
||
}
|
||
return 200, "创建成功"
|
||
|
||
@classmethod
|
||
def stop(cls, udid: str) -> Tuple[int, str]:
|
||
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, "操作成功"
|
||
|
||
@classmethod
|
||
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, "停止成功."
|
||
|
||
@classmethod
|
||
def _kill_thread(cls, tid: int) -> bool:
|
||
"""向原生线程 ID 抛 KeyboardInterrupt,强制跳出"""
|
||
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) |