2012-07-21 9 views
7

W doc funkcji qsize() jest napisane: Zwróć przybliżoną wielkość kolejki.Dlaczego kolejka Pythona zwraca przybliżony rozmiar w qsize()?

Dlaczego nie można po prostu zwrócić dokładnego rozmiaru tej kolejki? Rozumiem, że do kolejki można uzyskać dostęp za pomocą wielu wątków, ale w tej chwili wzywam funkcję, myślę, że nadal możliwe jest zwrócenie dokładnego rozmiaru tej chwili.

+1

Co chwila? Rozmiar kolejki mógł się zmienić podczas powrotu metody. –

Odpowiedz

24

Dzieje się tak dlatego, że dostęp do niego mają inne wątki. Zanim spróbujesz użyć rozmiaru, który otrzymasz z qsize(), kolejka mogła się zmienić. Byłoby lepiej, gdyby dokumentacja miała coś takiego:

Powoduje zwrócenie rozmiaru kolejki. Zwróć uwagę, że w środowisku wielowątkowym rozmiar może się zmienić w dowolnym momencie, czyniąc to tylko przybliżeniem rzeczywistego rozmiaru.

5

zgadzam się, że „w przybliżeniu” nie jest najwyraźniejszy dobór słów, ale jak wspomina Ned próbują zwrócić uwagę, że tylko dlatego, że wielkość kolejki w czasie t1 było 7 nie znaczy, że będzie nadal będzie rozmiar 7, gdy później popchniesz lub pop wartości.

Problem polega na tym, że rozmiar, który otrzymasz z qsize, będzie nadal poprawny, gdy przejdziesz do push/pop, wartość z tej kolejki może nieoczekiwanie zachowywać się w środowisku wielowątkowym.

Na przykład:

q = Queue() 
if q.qsize > 0: # size is 1 here 
    # another thread runs here and gets an item from your queue 
    # this get fails and throws an exception in your thread: 
    item = q.get(False) 
    # do whatever processing with item you need to do 

Jest przykładem LBYL „Patrząc przed skokiem” i jest to niebezpieczne ze względu na potencjalne wyścigu tutaj, gdy wiele wątków dostępu do kolejki.

W tym przypadku należy faworyzować EAFP lub „łatwiej jest prosić o przebaczenie niż pozwolenie” i wykonaj następujące czynności:

from Queue import Queue, Empty 
import time 
q = Queue() 
try: 
    item = q.get(False) 
    # do whatever processing with item you need to do 
except Empty: 
    time.sleep(1) 
+0

.. lub po prostu użyj semafora, aby zagwarantować, że kolejka ma wpis. –

+6

Kolejka jest już zsynchronizowana, nie dodawaj więcej na górze. Używanie 'q.get' z wyjątkiem jest najlepszym sposobem na uzyskanie wątku. –

Powiązane problemy