2014-10-27 14 views
5

Czy w Pythonie istnieje struktura danych przypominająca słownik blokujący? Ta struktura danych musi spełniać następujące wymagania:Blokowanie dict w Pythonie?

  • to musi być losowo dostępne i pozwalają na dowolny element, aby być modyfikowane/usunięte (nie tylko pierwszy lub ostatni)
  • musi mieć GET blokujący() i umieścić ()
  • musi być bezpieczny wątku

użyłbym kolejkę, ale mimo blokowania i bezpieczny wątku, to nie jest losowo dostępne. Dict też się nie blokuje (o ile chodzi o wiedzę Pythona). Jako przykład pomyśl o jednym wątku producenta dodającym pary klucz-wartość do takiej struktury danych (aktualizowanie wartości istniejących kluczy, jeśli już istnieją - jest to miejsce, w którym kolejka ich nie wycina) oraz blokowanie procesu roboczego przez dostawcę () i zużywanie tych par klucz-wartość, gdy tylko będą dostępne. Wielkie dzięki!

edytuj: Załóżmy, że producent odpytuje serwer CI i otrzymuje pary projektów. Generuje różnice w statusach projektu i umieszcza je we wspomnianej strukturze danych. Pracownik odbiera te aktualizacje statusu projektu i wyświetla je po kolei jako animację na ekranie.

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) 

Odpowiedz

2

Coś wzdłuż następujących linii powinno wystarczyć (niesprawdzone):

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() 

używa słownika dla kolejki oraz zmiennej stan na SZEREGOWANIE dostępu i sygnalizacji między wątkami.

+0

Równie dobrze użyj tutaj 'z self.cv' zamiast' acquire'/'release'. Twój kod jest niebezpieczny, gdy nie nadający się do użycia przedmiot jest "wsadzany" do dyktatury; użycie 'with' sprawia, że ​​jest bezpieczny. W Pythonie 3.2+ masz także 'wait_for', który jest trochę cukru syntaktycznego. I na koniec zwróć uwagę, że 'notify' może wymagać' notify_all', jeśli użyjesz tego, aby poczekać, aż dany klucz stanie się dostępny bez wprowadzania kilku zmiennych warunkowych. – Veedrac

+0

@Veedrac: Świetne punkty, wielkie dzięki. – NPE