JoinableQueue'对象不可迭代

0 投票
1 回答
1250 浏览
提问于 2025-04-18 10:52

假设我有一个队列:

myqueue = multiporcessing.JoinableQueue()

在我的代码中,父进程会把所有的对象(比如一个字符串)放入myqueue,这个myqueue会被子进程共享。子进程需要检查某个对象(比如xxx)是否在myqueue里,我尝试使用:

if xxx in [y for y in myqueue]

但我遇到了这样的错误:

'JoinableQueue' object is not iterable

我的问题是,还有没有其他方法可以让我实现上面的需求?或者有没有办法检查一个对象是否仍在队列中?

检查共享队列的原因是,队列中的对象是相互依赖的,每个对象都有一些状态,比如“运行中”、“等待中”、“已完成”。举个例子,对象'a'依赖于'A','A'和'a'会在父进程启动子进程之前被放入队列。当子进程从队列中获取'a'时,它需要检查'A'的状态。如果'A'的状态仍然是“等待中”,那么'a'就会被放回队列,除非'A'的状态是“已完成”。换句话说,'A'不再在myqueue里了。

1 个回答

1

JoinableQueue 这个东西不支持查看里面的内容(除非你算上 emptyfull)。

根据你想用这个队列做什么,你可能需要用不同的对象来存储你的队列。不过,有两种可能的解决办法:

  1. 如果你确定在你检查的时候没有其他进程会碰这个队列,你可以先 get 出所有的对象,看看你想找的东西是不是在里面,然后再按原来的顺序 put 回去。

  2. 如果只有子进程会 get 对象,你可以把这些对象放到另一个临时队列里。

第一种方法应该比较简单实现。第二种方法可能像这样:

class QueueView:
    def __init__(self, joinable):
        self.joinable = joinable
        self.other = collections.deque()
    def get(self, block=True, timeout=None):
        if self.other:
            return self.other.popleft()
        self.joinable.get(block, timeout)
    def __contains__(self, item):
        if item in self.other:
            return True
        try:
            while True:
                o = self.joinable.get(block=False)
                self.other.append(o)
        except Queue.Empty:
            pass
        return item in self.other

只有一个进程应该能看到 QueueView 对象,并通过这个视图对象从 JoinableQueueget 任何东西。任何数量的进程都可以往 JoinableQueueput 东西。

撰写回答