6

Voglio estrarre tutti gli elementi attualmente in una coda. C'è un altro thread che inserisce costantemente gli elementi nell'altra estremità e in ogni periodo voglio ottenere tutti gli elementi attualmente in coda.Modo preferito per svuotare multiprocessing.queue (-1) in python

C'è qualche motivo per preferire:

res = [] 
while q.qsize > 0 : 
    res.append(q.get()) 

o

res = [] 
while True : 
    try : 
     res.append(q.get(block=False)) 
    except Queue.Empty : 
     break 

Ora la documentazione specificamente dicono che il qsize()> 0 non sarà evitare che la coda di bloccare su un get, ma è vero solo nel caso in cui più thread possano prendere dall'output?

Coda. qsize() Restituisce la dimensione approssimativa della coda. Nota, qsize()> 0 non garantisce che un successivo get() non blocchi, né qsize() < maxsize garantisce che put() non bloccherà.

Ciò significa che il secondo modulo deve sempre essere preferito? EAFP e tutto il resto? Inoltre, c'è qualche costo per chiamare q.qsize()? Blocca l'altra estremità della coda per poter contare?

Credo di aver parlato con me stesso del secondo modulo, ma mi sembra molto meno pulito.

risposta

5

Sì, si dovrebbe sempre utilizzare la seconda variante: la documentazione delle API è (dovrebbe) generalmente più affidabile delle specifiche non documentate dell'implementazione. Anche se l'attuale implementazione multiprocessing funziona in modo tale che nel tuo caso speciale, get() non bloccherà se qsize() > 0, non è garantito che rimarrà in questo modo nelle future versioni di Python, perché la documentazione già afferma chiaramente che non lo è.

Detto questo, con le versioni correnti di Python la prima versione dovrebbe funzionare in modo affidabile e purché si abbia solo un processo di consumo. Chiamare qsizeintenally invokes sem_getvalue on Linux and WaitForSingleObjectEx on Windows; entrambi non bloccano nulla. (Per la chiamata Linux, questo è documentato nella manpage, per la chiamata Windows, è una forte ipotesi.)

Si noti che se si dispone di più utenti e si desidera assicurarsi che uno di essi legga l'intera coda, è necessario usare un blocco aggiuntivo che racchiude il tuo loop!