6

Ich möchte alle Elemente in einer Warteschlange ziehen. Es gibt einen anderen Thread, der fortwährend Elemente in das andere Ende legt, und in jedem Zeitraum möchte ich alle Elemente, die gerade in der Warteschlange sind, erhalten.Bevorzugte Methode zum Leeren von multiprocessing.queue (-1) in Python

Gibt es einen Grund zu bevorzugen:

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

oder

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

Nun sind die speziell docs sagen, dass die WGröße()> 0 wird die Warteschlange nicht daran hindern, ein Get blockiert, aber Ist dies nur in dem Fall der Fall, wenn mehrere Threads von der Ausgabe genommen werden können?

Warteschlange. qsize() Geben Sie die ungefähre Größe der Warteschlange an. Beachten Sie, qsize()> 0 garantiert nicht, dass eine nachfolgende get() wird nicht blockiert, noch wird qsize() < maxsize Garantie, dass put() wird nicht blockiert.

Bedeutet dies, dass die zweite Form immer bevorzugt werden sollte? EAFP und all das? Gibt es irgendwelche Kosten für den Aufruf von q.qsize()? Blockiert es das andere Ende der Warteschlange, um zu zählen?

Ich denke, ich habe mich in die zweite Form überreden, aber es scheint mir viel weniger sauber zu sein.

Antwort

5

Ja, Sie sollten immer die zweite Variante verwenden: Dokumentation von APIs sollte (sollte) in der Regel zuverlässiger sein als undokumentierte Besonderheiten der Implementierung. Auch wenn die aktuelle multiprocessing Implementierung so funktioniert, dass in Ihrem speziellen Fall get() nicht blockiert wird, wenn , ist es nicht garantiert, dass es in zukünftigen Versionen von Python so bleiben wird, weil die Dokumentation bereits klar besagt, dass es nicht ist.

Das heißt, mit den aktuellen Versionen von Python sollte die erste Version zuverlässig funktionieren, solange Sie nur einen konsumierenden Prozess haben. Rufen qsizeintenally invokes sem_getvalue on Linux and WaitForSingleObjectEx on Windows; Beide sperren nichts. (Für den Linux-Aufruf ist dies in der Manpage dokumentiert, für den Windows-Aufruf ist es eine starke Vermutung.)

Beachten Sie, dass Sie, wenn Sie mehrere Verbraucher haben und sicherstellen möchten, dass einer von ihnen die gesamte Warteschlange liest Verwenden Sie ein zusätzliches Schloss, das Ihre Schleife umschließt!