You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

wxPython结合pypubsub的多线程程序中Thread1被Thread2阻塞原因问询

阻塞原因

PyPubSub默认采用同步消息分发机制:当你在任意线程调用pub.sendMessage()时,所有订阅对应主题的回调函数,都会直接在调用sendMessage的当前线程(也就是你这里的Thread1)中串行执行,不会自动切换到回调函数所属对象所在的线程。你虽然把my_func定义在Thread2类中,但只要是Thread1触发的消息发送,这个函数就会在Thread1的上下文里运行,自然会阻塞Thread1的后续逻辑。

解决方案

你需要给Thread2增加线程安全的任务队列,由Thread2自身消费队列中的任务,让my_func真正在Thread2的线程中执行,修改方案如下:

  1. 给Thread2新增线程安全的任务队列,用于接收外部传入的执行请求
  2. 将PyPubSub的订阅逻辑移到Class1侧,收到消息后仅做入队操作,不会阻塞Thread1
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 13:06:05