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):
self._devices: dict[str, DeviceInfo] = {}
self._lock = threading.Lock()
self._lock = threading.RLock() # 可重入锁: update_xxx 内部调用 get_or_create
self._callbacks: list[Callable] = []
def on_change(self, callback: Callable):
+1 -8
View File
@@ -3,7 +3,6 @@ MQTT 客户端封装
"""
import json
import time
import sys
import threading
from typing import Callable, Optional
from dataclasses import dataclass
@@ -123,13 +122,7 @@ class MqttClient:
if not self._client or not self._connected:
raise ConnectionError("MQTT 未连接")
data = json.dumps(payload, ensure_ascii=False)
print(f"[MqttClient] publish topic={topic} qos={qos}", flush=True)
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
self._client.publish(topic, data, qos=qos)
def subscribe(self, topic: str, qos: int = 1):
"""订阅主题"""