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

多进程环境下Event_Handler事件队列未更新问题求助

问题根源

Python多进程下每个子进程都有独立的内存空间。你在EV_Main.run里创建的两个子进程,会各自复制一份父进程的self.e_h实例——也就是说,create_events进程往自己副本的列表里加事件,handle_events进程看的却是另一个完全独立的副本,自然永远是空的。

你之前查的实例ID只是单个进程内部的标识,不是跨进程的唯一ID,所以看起来相同其实是两个完全不同的对象。

解决方案

要实现跨进程数据共享,必须用multiprocessing提供的共享数据结构,下面给两种可行方案:

方案1:用Manager创建共享双端队列

修改Event_Handler,用Manager生成跨进程共享的deque:

from multiprocessing import Lock, Manager

class Event_Handler:
    def __init__(self):
        manager = Manager()
        # 创建跨进程共享的deque列表
        self._to_handle_list = [manager.deque() for _ in range(Event_Prio.get_num_prios())]            
        self._controll_handler= None
        self._process_lock = Lock() 
       
    def init(self, controll_EV_handler):
        self._controll_handler= controll_EV_handler

    def new_event(self, event):          
        with self._process_lock:
            self._to_handle_list[event.get_Prio()].append(event)
 
    def handle_event(self):         
        self._process_lock.acquire()
        try:
            for i in range(Event_Prio.get_num_prios()):  
                if self._to_handle_list[i]: 
                    event = self._to_handle_list[i].popleft()
                    self._process_lock.release()
                    if self._controll_handler:
                        self._controll_handler.controll_event(event)
                    return
        finally:
            # 确保锁无论如何都会释放,防止死锁
            if self._process_lock.locked():
                self._process_lock.release()

    def create_Event(self, prio, type):
        return Event(prio, type)

方案2:用PriorityQueue(更简洁)

如果你的事件优先级逻辑可以适配,直接用PriorityQueue更省心,它自带进程安全:

from multiprocessing import PriorityQueue

class Event_Handler:
    def __init__(self):
        self._event_queue = PriorityQueue()            
        self._controll_handler= None
       
    def init(self, controll_EV_handler):
        self._controll_handler= controll_EV_handler

    def new_event(self, event):          
        # 优先级队列自动按优先级排序,注意数值越小优先级越高
        self._event_queue.put((event.get_Prio(), event))
 
    def handle_event(self):         
        try:
            # 非阻塞获取,避免空队列时一直等待
            prio, event = self._event_queue.get(block=False)
            if self._controll_handler:
                self._controll_handler.controll_event(event)
        except:
            # 队列为空时跳过
            pass

    def create_Event(self, prio, type):
        return Event(prio, type)

关键提醒

  • 普通的deque/列表不能跨进程共享,必须用multiprocessing提供的共享结构
  • 使用锁时一定要加异常处理,确保锁能正常释放,避免死锁
  • Manager是通过进程间通信实现的,性能略低于本地队列,但事件系统场景下完全够用

内容的提问来源于stack exchange,提问作者Marsh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:25:29