2014-04-30 9 views
8

In Java, c'è java.util.concurrent.SynchronousQueue, una coda senza capacità di archiviazione. I thread che cercano di mettere/ottenere il valore si bloccano sempre fino a quando un altro thread tenta di ottenere/inserire un valore rispettivamente.Ottimo modo per creare una coda di blocco a lunghezza zero in Python

Quali sono i modi migliori per fare lo stesso in Python? Cioè Voglio un modo per passare i valori da un set di uno o più thread a un altro set di uno o più thread senza che un valore sia mai "appartenente" a un thread in uno dei due gruppi.

di Python queue.Queue non consente la lunghezza di essere 0, specificando un valore non positivo per la capacità massima crea una coda infinita.

risposta

2

Ho la sensazione che il seguente potrebbe essere deadlock city, ma sarebbe qualcosa come il seguente lavoro?

class SynchronousQueue(object): 
    def __init__(self): 
     self.ready_to_get = Queue(1) 
     self.queue = Queue(1) 

    def get(self): 
     self.ready_to_get.put('ready', block=True) 
     return self.queue.get(block=True) 

    def put(self, item): 
     self.ready_to_get.get(block=True) 
     self.queue.put(item, block=True) 

Una coda regolare supporta la metà di ciò che si vuole (il getter attesa sul putter), in modo che possiamo cercare di implementare il contrario bloccando la messa fino a quando ha iniziato una get.

+0

Non credo che modifica il comportamento se hai fatto queste code lunghezza illimitata, ma potrebbe essere più efficace: ciò significherebbe il 'ready_to_get.put()' non potrebbe mai bloccare (ma va bene come il 'queue.get()' bloccherà ancora) e allo stesso modo 'queue.put()' non bloccherebbe ma non lo raggiungerebbe a meno che qualcosa stava cercando di "ottenere". – Duncan

+0

Volevo provare a rendere conto della situazione in cui ci sono due getter in coda, ma solo uno scrittore disponibile. Ma penso che tu abbia ragione, siamo coperti dall'ottenere comunque. –

2

È possibile utilizzare Queue.join() e Queue.task_done() di bloccare fino a quando il get() ha completato:

class SynchronousQueue(object): 

    def __init__(self): 
     self.q = Queue(1) 
     self.put_lock = RLock() 

    def get(self): 
     value = self.q.get(block=True) 
     self.q.task_done() 
     return value 

    def put(self, item): 
     with self.put_lock: 
      self.q.put(item, block=True) 
      self.q.join() 
Problemi correlati