【问题标题】:Python signal between functions to remove busy waiting函数之间的 Python 信号以消除繁忙的等待
【发布时间】:2015-09-11 12:46:03
【问题描述】:

我只是想在 Python 中实现一个简单的观察者模式,但遇到了一个问题。这是我的代码:

class Observable:
    def __init__(self):
    self.__observers = []

    def register_observer(self, observer):
        self.__observers.append(observer)

    def notify_observers(self, data):
        for observer in self.__observers:
            observer.notify(self, data)

class Observer:

    def __init__(self, observable):
        observable.register_observer(self)
        self.data_present = False
        self.data = ''

    def notify(self, observable, data):
        self.data_present = True
        self.data = data

    def wait(self):
        while True:
            if not self.data_present:
                time.sleep(5)

            else:
                break

        return self.data

在这里,我想消除 Observer.wait() 中的忙碌等待(行 time.sleep(5)。我怎样才能向这个函数发出信号?

【问题讨论】:

  • 这不是你可以使用 asyncio 的地方吗?
  • 查看asyncio 模块的示例。特别是,您可能想要使用coroutines
  • @Evert,我希望我的观察者是同步的,并在他们继续执行之前等待消息发布。

标签: python observer-pattern busy-waiting


【解决方案1】:

您根本不需要wait 功能——只需在notify 中做您需要做的事情(处理数据、记录数据、破坏/旋转/折叠数据,等等)。

如果您使用线程,请查看Queue.Queue 类:它允许多个线程在数据可用性上同步而无需忙于等待——只需让notify 方法将数据推送到Queue 和@ 987654327@可以等。请注意,使用Threading 模块中的一些其他功能可能有一个更优雅的解决方案。

附带说明一下,self.__observers 中也不需要双下划线——self.observers 就可以了。

【讨论】:

  • 我希望我的观察者是同步的。我希望他们等到有数据发布后再继续执行。我认为如果我在 notify 中做所有事情,我的观察者不会是异步的吗?
  • 你在使用线程吗?如果没有,一切都已经同步了。如果您正在使用线程,请查看Queue - 您的notify 可以将数据提交给它,而您的wait(或您实际调用的任何名称)可以简单地尝试从get Queue这将阻塞直到数据出现(没有忙等待)。至于notify,只有Observable 调用它,所以在有可用数据之前,里面什么都不会运行。
  • 是的,我使用的是线程。这个解决方案工作得很好。如果在运行多个线程时创建了许多 Queue.Queue() 实例,是否存在问题? PS:您可以使用此信息编辑您的答案以便我接受吗?
【解决方案2】:

您可以使用yield 暂停某个函数,等待某个值(阻塞,不忙于等待)。

def f():
    print('f: i am waiting for something...')
    c = yield
    print('f: i got %s' % c)
    yield None

另一方面,您调用.send(val) 以恢复其执行:

>>> g=f()
>>> next(g)
f: i am waiting for something...
>>> g.send(123)
f: i got 123
>>>

注意f() 末尾的附加yield None,它可以防止StopIteration 异常在您调用raised 时成为raised。

【讨论】:

    猜你喜欢
    • 2012-06-29
    • 2016-11-10
    • 1970-01-01
    • 2011-12-08
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    相关资源
    最近更新 更多