Если вы всегда вытаскиваете все доступные элементы из очереди, есть ли смысл использовать очередь, а не просто список с блокировкой? то есть:
from __future__ import with_statement
import threading
class ItemStore(object):
def __init__(self):
self.lock = threading.Lock()
self.items = []
def add(self, item):
with self.lock:
self.items.append(item)
def getAll(self):
with self.lock:
items, self.items = self.items, []
return items
Если вы также извлекаете их по отдельности и используете блокирующее поведение для пустых очередей, вам следует использовать Очередь, но ваш вариант использования выглядит намного проще и может быть лучше реализован с помощью вышеуказанного подхода.
[Edit2] Я пропустил тот факт, что вы опрашиваете очередь из цикла простоя, и из вашего обновления я вижу, что проблема не связана с конфликтом, поэтому ниже подход не имеет отношения к вашей проблеме. Я оставил это в случае, если кто-нибудь найдет вариант блокировки этого полезного:
В тех случаях, когда вы хотите заблокировать, пока не получите хотя бы один результат, вы можете изменить приведенный выше код, чтобы дождаться, когда данные станут доступны благодаря сигналу потока производителя. Например.
class ItemStore(object):
def __init__(self):
self.cond = threading.Condition()
self.items = []
def add(self, item):
with self.cond:
self.items.append(item)
self.cond.notify() # Wake 1 thread waiting on cond (if any)
def getAll(self, blocking=False):
with self.cond:
# If blocking is true, always return at least 1 item
while blocking and len(self.items) == 0:
self.cond.wait()
items, self.items = self.items, []
return items