Wenn Sie immer alle verfügbaren Elemente aus der Warteschlange entfernen, gibt es einen wirklichen Vorteil bei der Verwendung einer Warteschlange statt nur einer Liste mit einer Sperre? dh:
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
Wenn Sie auch einzeln, und die Nutzung des Sperrverhalten für leere Warteschlangen ziehen, dann sollten Sie Queue verwenden, aber Ihren Anwendungsfall sieht viel einfacher, und vielleicht besser durch die serviert werden über dem Ansatz.
[Edit2] Ich habe die Tatsache verpasst, dass Sie die Warteschlange von einer Leerlaufschleife abfragen, und von Ihrem Update sehe ich, dass das Problem nicht mit Konflikten verbunden ist, so ist der folgende Ansatz nicht t wirklich relevant für Ihr Problem. Ich habe es gelassen, falls jemand eine blockierende Variante dieses nützlichen findet:
Für Fälle, in denen Sie blockieren möchten, bis Sie mindestens ein Ergebnis erhalten, können Sie den obigen Code ändern, um auf Daten zu warten indem es vom Produzenten-Thread signalisiert wird. Z.B.
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
Es könnte lange Wartezeiten verursachen, wenn er es in einer Weile 1: busyloop anruft. Wenn dies der Fall ist, würde der Verbraucher nicht nur die Zeitfenster des Produzenten reduzieren, sondern würde auch viel Zeit darauf verwenden, die Warteschlangensperre zu halten, was möglicherweise den Produzenten in die Flucht schlagen würde. (Dies ist wahrscheinlicher, wenn er mehrere Consumer-Threads hat.) – Brian
Guter Punkt Brian. Ich hatte den Eindruck, dass Eliben das nicht alles nannte, aber ich könnte mich irren - Eliben? –
Hoppla, da hast du recht - ich habe den Teil vermisst, als ich ihn in einem Leerlauf aufgerufen habe. Das wäre nicht genug, um solche Probleme zu verursachen. – Brian