函数之间的Python信号可以消除繁忙的等待

时间:2015-06-25 04:48:04

标签: python observer-pattern busy-waiting

我只是想在Python中实现一个简单的Observer模式并遇到问题。这是我的代码:

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)。我怎么能发信号给这个函数?

2 个答案:

答案 0 :(得分:1)

您根本不需要wait功能 - 只需在notify中执行您需要的操作(处理数据,记录数据,破坏/转动/折叠数据,无论)。

如果您正在使用线程,请查看Queue.Queue类:它允许多个线程在没有繁忙等待的情况下同步数据可用性 - 只需将notify方法推送数据放入{{ 1}},Queue可以等待它。请注意,使用Threading模块中的一些其他功能可能会有更优雅的解决方案。

作为旁注,您也不需要wait中的双下划线 - 只需self.__observers即可。

答案 1 :(得分:1)

您可以使用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
>>>

请注意yield None末尾的其他f(),以防止在您致电StopIteration时出现raise例外.send()