Si siempre está quitando todos los artículos disponibles de la cola, ¿hay algún punto real en el uso de una cola, en lugar de solo una lista con un candado? es decir:
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
Si también está tirando de ellos de forma individual, y haciendo uso de la conducta de bloqueo para las colas vacías, se debe usar la cola, pero su caso de uso se ve mucho más simple, y podría ser mejor servido por la enfoque anterior.
[Edit2] me había perdido el hecho de que eres el sondeo de la cola de un bucle de inactividad, y de su actualización, veo que el problema no está relacionado con la contención, por lo que la aproximación por debajo de ISN' realmente relevante para su problema Lo dejé en caso de que alguien encuentre una variante de bloqueo de este útil:
Para los casos en los que desea bloquear hasta obtener al menos un resultado, puede modificar el código anterior para esperar que los datos estén disponibles a través de ser señalado por el hilo productor. P.ej.
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
Podría causar largas esperas si lo llama desde hace tiempo 1: busyloop. De ser así, el consumidor no solo estaría reduciendo el tiempo de espera del productor, sino que también pasaría mucho tiempo manteniendo el bloqueo de la cola, lo que podría bloquear al productor. (Esto es más probable si tiene múltiples hilos de consumo.) – Brian
Buen punto Brian. Me dio la impresión de que eliben no llamaba a todo esto con frecuencia, pero podría estar equivocado, ¿vale? –
Vaya, tiene razón, me perdí la parte de llamarlo en un evento inactivo. Eso no sería suficiente para causar tales problemas. – Brian