wxPython结合pypubsub的多线程程序中Thread1被Thread2阻塞原因问询
阻塞原因
PyPubSub默认采用同步消息分发机制:当你在任意线程调用pub.sendMessage()时,所有订阅对应主题的回调函数,都会直接在调用sendMessage的当前线程(也就是你这里的Thread1)中串行执行,不会自动切换到回调函数所属对象所在的线程。你虽然把my_func定义在Thread2类中,但只要是Thread1触发的消息发送,这个函数就会在Thread1的上下文里运行,自然会阻塞Thread1的后续逻辑。
解决方案
你需要给Thread2增加线程安全的任务队列,由Thread2自身消费队列中的任务,让my_func真正在Thread2的线程中执行,修改方案如下:
- 给Thread2新增线程安全的任务队列,用于接收外部传入的执行请求
- 将PyPubSub的订阅逻辑移到Class1侧,收到消息后仅做入队操作,不会阻塞Thread1
- Thread2的run循环中新增队列轮询逻辑,有任务时取出执行,无任务时继续跑原有定期操作
修改后的代码示例:
from queue import Queue, Empty from threading import Thread from pubsub import pub import time # Thread2修改后代码 class Thread2(Thread): def __init__(self, parent): super().__init__() self.parent = parent self.task_queue = Queue() self.daemon = True # 设为守护线程,避免程序退出时线程残留 def run(self): while True: # 轮询队列,超时设为100ms避免卡死原有定期任务 try: task = self.task_queue.get(timeout=0.1) if task["type"] == "events": self.my_func(task["message"]) self.task_queue.task_done() except Empty: pass # 原有定期执行的逻辑写在这里 # do stuff time.sleep(1) # 示例间隔,按你原有逻辑调整 def my_func(self, message): # 原有逻辑保留 # do other stuff using the message # call parent functions pass # Class1修改后代码 class Class1: def __init__(self): self.t2 = Thread2(self) self.t2.start() # 订阅逻辑移到此处,收到消息后仅做入队操作 pub.subscribe(self.on_events_received, "events") def on_events_received(self, message): self.t2.task_queue.put({"type": "events", "message": message})
内容的提问来源于stack exchange,提问作者Deffo
相关产品推荐
相关产品推荐

