fix: DeviceManager 死锁 — threading.Lock 改为 RLock

根因: update_from_dev_info/update_loop_data/update_event/update_heartbeat
      在 with self._lock 块内调用 get_or_create(), 后者再次 with self._lock.
      Python threading.Lock 不可重入 → 永久阻塞 → GUI 无响应.

修复: self._lock = threading.RLock() (可重入锁)

清理: mqtt_client.py 移除 debug print 和未使用的 sys import
This commit is contained in:
wangfq
2026-07-07 17:36:35 +08:00
parent c98aa5b0bb
commit 5e4e1b1ec7
2 changed files with 2 additions and 9 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ class DeviceManager:
def __init__(self): def __init__(self):
self._devices: dict[str, DeviceInfo] = {} self._devices: dict[str, DeviceInfo] = {}
self._lock = threading.Lock() self._lock = threading.RLock() # 可重入锁: update_xxx 内部调用 get_or_create
self._callbacks: list[Callable] = [] self._callbacks: list[Callable] = []
def on_change(self, callback: Callable): def on_change(self, callback: Callable):
+1 -8
View File
@@ -3,7 +3,6 @@ MQTT 客户端封装
""" """
import json import json
import time import time
import sys
import threading import threading
from typing import Callable, Optional from typing import Callable, Optional
from dataclasses import dataclass from dataclasses import dataclass
@@ -123,13 +122,7 @@ class MqttClient:
if not self._client or not self._connected: if not self._client or not self._connected:
raise ConnectionError("MQTT 未连接") raise ConnectionError("MQTT 未连接")
data = json.dumps(payload, ensure_ascii=False) data = json.dumps(payload, ensure_ascii=False)
print(f"[MqttClient] publish topic={topic} qos={qos}", flush=True) self._client.publish(topic, data, qos=qos)
try:
info = self._client.publish(topic, data, qos=qos)
print(f"[MqttClient] publish done mid={info.mid}", flush=True)
except Exception as e:
print(f"[MqttClient] publish EXCEPTION: {e}", flush=True)
raise
def subscribe(self, topic: str, qos: int = 1): def subscribe(self, topic: str, qos: int = 1):
"""订阅主题""" """订阅主题"""