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

8 投票
2 回答
608 浏览
提问于 2025-04-18 04:53

在Java中,有一个叫做 java.util.concurrent.SynchronousQueue 的东西,它是一个没有存储空间的队列。也就是说,当一个线程想要放入或取出一个值时,它会一直等待,直到另一个线程去取出或放入一个值。

那么在Python中,有什么好的方法可以做到类似的事情呢?也就是说,我想要一种方式,可以让一组线程把值传递给另一组线程,而这些值在任何一组线程中都不会“属于”某个线程。

Python的 queue.Queue 不允许长度为 0,如果你设置最大容量为一个非正数值,它就会变成一个没有上限的队列。

2 个回答

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)

一个普通的队列只能支持你想要的功能的一半(也就是取数据的操作会等着放数据的操作),所以我们可以尝试反过来做,也就是在开始取数据之前,先让放数据的操作处于阻塞状态。

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()

撰写回答