python条件变量忙着等待吗?

时间:2014-02-28 14:43:25

标签: python concurrency

我有一个多线程程序,主线程将在任意时间点将事件放在队列中,如果队列不为空,我只希望后台线程运行。即,我不希望我的线程忙等待,我希望它能够进入睡眠状态,只有在收到通知时才会被唤醒。我的类中有一个名为queueNotEmpty的条件变量,只要有一些东西被添加到队列中,主线程就会调用notify()。以下是否满足我的需求,或者这仍然在wait()电话内等待?

while(not self.terminate):
    try:
        eventName, info = self.eventQueue.get(block=False)
        event = trigger(eventName, info)
    except Queue.Empty:
        self.queueNotEmpty.acquire()
        self.queueNotEmpty.wait()
        self.queueNotEmpty.release()

2 个答案:

答案 0 :(得分:2)

你正打算打开门。这基本上和你上面的代码一样,没有代码中的额外复杂性,并且由于潜在的竞争条件没有循环周期。

while(not self.terminate):
    eventName, info = self.eventQueue.get()
    event = trigger(eventName, info)

队列阻止正在等待。

更新:Queue的内部工作原理在博客文章"Python threads synchronization: Locks, RLocks, Semaphores, Conditions, Events and Queues"中有所描述。根据该消息来源,它实现如下:

def get(self, block=True, timeout=None):
    ...
    self.not_empty.acquire()
    try:
        ...
        elif timeout is None:
            while not self._qsize():
                self.not_empty.wait()
        item = self._get()
        self.not_full.notify()
        return item
    finally:
        self.not_empty.release()

答案 1 :(得分:1)

如果使用.get()(默认值)在Queue.Queue对象上调用block=True,则您的线程将自动暂停,直到有从队列中读取的内容为止。如果几个线程都试图读取队列,那么就无法保证哪个线程会设法读取它。

Queue.Queue的主要目的是启用可靠的线程间通信,因此阻塞和同步就会被解雇。