在Python中构建阻塞的零长度队列的好方法

8
在Java中,有一个没有储存容量的队列java.util.concurrent.SynchronousQueue。尝试放置/获取值的线程总是阻塞,直到另一个线程尝试获取/放置一个值。
那么在Python中如何实现相同的功能呢?即我想要一种方法将一个或多个线程集合中的值传递给另一个或多个线程集合,而不会使任何一个值“属于”任何一个线程组。
Python的queue.Queue不允许长度为0,指定非正值的最大容量会创建一个无限制的队列。
2个回答

4
你可以使用Queue.join()Queue.task_done()来阻塞,直到get()方法完成:
class SynchronousQueue(object):

    def __init__(self):
        self.q = Queue(1)
        self.put_lock = RLock()

    def get(self):
        value = self.q.get(block=True)
        self.q.task_done()
        return value

    def put(self, item):
        with self.put_lock:
            self.q.put(item, block=True)
            self.q.join()

2
我感觉以下内容可能会出现死锁,但是像以下这样的代码是否可行呢?
class SynchronousQueue(object):
    def __init__(self):
        self.ready_to_get = Queue(1)
        self.queue = Queue(1)

    def get(self):
        self.ready_to_get.put('ready', block=True)
        return self.queue.get(block=True)

    def put(self, item):
        self.ready_to_get.get(block=True)
        self.queue.put(item, block=True)

一个普通队列只支持你想要的一半功能(getter等待putter),因此我们可以尝试通过阻止put直到get已开始来实现反向操作。


我认为如果您将这些队列设置为无限长度,它不会改变行为,但可能更有效:这意味着 ready_to_get.put() 永远不会被阻塞(但是当 queue.get() 仍然被阻塞时没有关系),同样的,queue.put() 不会被阻塞,但如果没有任何东西尝试取出,则无法到达。 - Duncan
我想尝试考虑这样一种情况:有两个getter排队等待,但只有一个writer可用。但我认为你是对的,我们已经通过get得到了覆盖。 - Jon Betts

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接