2014-10-27 10 views
5

Gibt es in Python eine Datenstruktur, die einem blockierenden Wörterbuch ähnelt? Diese Datenstruktur muss diese Anforderungen erfüllen:Blockieren von Diktaten in Python?

  • muss jedes Element zufällig zugänglich und ermöglicht es sein zu modifizierenden/gelöscht (nicht nur die erste oder letzte)
  • es eine Sperr get haben muß() und setzt ()
  • muss thread-safe

ist ich eine Warteschlange verwendet haben würde, aber, obwohl blockiert und Thread-sicher, es ist nicht zufällig zugänglich ist. Ein Diktat blockiert auch nicht (soweit mein Python-Wissen geht). Denken Sie beispielsweise an einen Producer-Thread, der Schlüssel/Wert-Paare zu einer solchen Datenstruktur hinzufügt (Aktualisieren von Werten für vorhandene Schlüssel, wenn diese bereits vorhanden sind.) und konsumieren diese Schlüssel-Wert-Paare, sobald sie verfügbar sind. Vielen vielen Dank!

bearbeiten: Angenommen, der Producer fragt einen CI-Server ab und ruft Projektstatus-Paare ab. Es erzeugt die Unterschiede in den Projektstatus und setzt sie in die oben erwähnte Datenstruktur. Der Mitarbeiter nimmt diese Aktualisierungen des Projektstatus auf und zeigt sie einzeln als Animation auf dem Bildschirm an.

class Producer: 
    def generateProjectStatusChanges(): 
    ... 
    def updateSuperAwesomeDataStructure(changes): 
    for (proj, stat) in changes: 
     #queue won't do cause the update could take place in the middle of the queue 
     #hence the dict behavior 
     superAwesomeDS.putOrUpdate(proj, stat) 
    def watchForUpdates(): 
    changes = generateProjectStatusChanges() 
    updateSuperAwesomeDataStructure(changes) 
    time.sleep(self.interval) 

class Worker: 
    def blockingNotifyAnimation(): 
    ... 
    def watchForUpdates(): 
    while true: 
     proj, stat = superAwesomeDS.getFirstPair() #or any pair really 
     blockingNotifyAnimation(proj, stat) 

Antwort

2

Etwas in den folgenden Zeilen sollte den Trick (ungetesteten) tun:

class UpdatableBlockingQueue(object): 

    def __init__(self): 
    self.queue = {} 
    self.cv = threading.Condition() 

    def put(self, key, value): 
    with self.cv: 
     self.queue[key] = value 
     self.cv.notify() 

    def pop(self): 
    with self.cv: 
     while not self.queue: 
     self.cv.wait() 
     return self.queue.popitem() 

es ein Wörterbuch für die Warteschlange verwendet und eine Bedingungsvariable für den Zugang Serialisieren und Signalisierung zwischen Threads.

+0

Könnte auch ''self.cv'' anstelle von 'acquire' /' release' verwenden. Ihr Code ist gefährlich, wenn ein nicht abspeicherbarer Gegenstand in das Diktat "eingesetzt" wird; Verwenden von 'mit' macht es sicher. Auf Python 3.2+ hast du auch 'wait_for', was ein wenig Syntaxzucker ist. Beachten Sie außerdem, dass "notify" möglicherweise zu "notify_all" werden muss, wenn Sie darauf warten, dass ein bestimmter Schlüssel verfügbar wird, ohne mehrere Bedingungsvariablen zu erstellen. – Veedrac

+0

@Veedrac: Tolle Punkte, vielen Dank. – NPE

Verwandte Themen