如何防止共享队列中的重复值

时间:2011-09-18 19:46:49

标签: python queue

生产者线程查询数据存储并将对象放入队列。然后,每个消费者线程将从共享队列中拉出一个对象,并对外部服务进行非常长的调用。当调用返回时,使用者将对象标记为已完成。

我的问题是我基本上必须等到队列空了才能让生产者再次添加它,否则我冒着重复发送的风险。

[编辑]有人问了一个关于IRC的好问题,我想我会在这里添加答案。问题是,“为什么你的制作人会产生重复?”答案基本上是生产者产生重复,因为我们不跟踪每个对象的“发送”状态,只是“发送”或“未发送”。

有没有办法可以检查队列中的重复项?

3 个答案:

答案 0 :(得分:3)

在我看来,在队列中拥有重复的对象并不是一个真正的问题;你只想确保每个对象只进行一次处理。

如果是这样,我建议您让消费者线程使用一个集合来跟踪已经看过的对象。如果对象不在集合中,则添加并处理它;如果它在集合中,则将其视为重复。

如果这是一个长时间运行的系统,而不是一个集合,请使用OrderedDict来跟踪看到的对象。然后不时清理OrderedDict中最旧的条目。

答案 1 :(得分:1)

如果你谈论Queue模块中的类:遵循API,就无法检测队列是否包含给定对象。

答案 2 :(得分:0)

将对象标记为已完成是什么意思?您是否将对象留在队列中并更改标志?或者您的意思是您将对象标记为已在数据存储中完成。如果是前者,队列怎么会变空?如果是后者,为什么不在开始处理之前从队列中删除对象?

假设您希望能够处理处理失败且不丢失数据的情况,一种方法是创建单独的工作队列和处理队列。然后,当消费者从工作队列中提取作业时,他们将其移动到处理队列并启动对外部服务的长时间运行调用。返回时,它可以标记数据完成并将其从处理队列中删除。如果为数据放入处理队列时添加字段,则可能会运行定期作业,检查超过特定时间的处理作业并尝试重新处理它们(在重新启动之前更新时间戳)。