是否应该在每个单独的线程中通知观察者?

Seb*_*ian 9 multithreading observer-pattern

我知道这听起来很重,但我正试图解决一个假设的情况.想象一下,你有一些物体的N个观察者.每个人都对对象状态感兴趣.应用Observer模式时,可观察对象倾向于迭代调用observer notify()|update()方法的观察者列表.

现在想象一下,特定的观察者有很多与可观察对象的状态有关的工作.例如,这会减慢上一次通知的速度.

因此,为了避免减慢对所有观察者的通知,我们可以做的一件事是在一个单独的线程中通知观察者.为了实现这一点,我想每个观察者都需要一个线程.这是一个痛苦的开销,我们正在努力避免因繁重工作导致的通知减慢.如果使用线程方法,最慢的是减速,是由无限循环引起的死线程.阅读这本有经验的程序员会很棒.

  • 有多年设计问题的人会怎么想?
  • 这是一个没有财务解决方案的问题吗?
  • 这是一个非常糟糕的主意吗?为什么?

这是一个模糊的例子,以展示并希望澄清我甚至没有测试的基本思想:

class Observable(object):
    def __init__(self):
        self.queues = {}

    def addObserver(self, observer):
        if not observer in self.queues:
            self.queues[observer] = Queue()
            ot = ObserverThread(observer, self.queues[observer])
            ot.start()

    def removeObserver(self, observer):
        if observer in self.queues:
            self.queues[observer].put('die')
            del self.queues[observer]

    def notifyObservers(self, state):
        for queue in self.queues.values():
            queue.put(state)

class ObserverThread(Thread):
    def __init__(self, observer, queue):
        self.observer = observer
        self.queue = queue

    def run(self):
        running = True
        while running:
            state = self.queue.get()
            if state == 'die':
                running = False
            else:
                self.observer.stateChanged(state)
Run Code Online (Sandbox Code Playgroud)

Lio*_*gan 7

你走在正确的轨道上.

每个观察者通常拥有自己的输入队列和自己的消息处理线程(或者更好:队列将拥有该线程,并且观察者将拥有该队列).请参见活动对象模式.

然而,有一些陷阱:

  • 如果您有100或1000个观察者,则可能需要使用线程池模式
  • 请注意,您将无法控制将要处理事件的顺序(哪个观察者首先处理事件).这可能是一个非问题,或者可能会打开一个非常难以检测的Pandora盒子.这取决于您的具体应用.
  • 您可能必须处理在通知者之前删除观察者的情况.这可能有点难以正确处理.
  • 您需要实现消息而不是调用函数.消息生成可能需要更多资源,因为您可能需要分配内存,复制对象等.您甚至可能希望通过为常见消息类型实现消息池来优化(您可以选择实现包装此类池的消息工厂) ).
  • 为了进一步优化,您可能希望生成一条消息并将其发送给所有观察者(而不是生成相同消息的多个副本).您可能需要为您的消息使用一些引用计数机制.