2012-07-21 24 views
7

Trong các doc của qsize() nó nói: Trả về kích thước gần đúng của hàng đợi.Tại sao Hàng đợi của Python trả về kích thước gần đúng trong qsize()?

Tại sao nó không thể trả về kích thước chính xác của Hàng đợi này? Tôi hiểu Hàng đợi có thể được truy cập bởi nhiều chủ đề, nhưng tại thời điểm tôi gọi chức năng tôi nghĩ rằng nó vẫn có thể trả lại kích thước chính xác của thời điểm đó.

+1

thời điểm gì? Kích thước hàng đợi có thể đã thay đổi trong quá trình trả về phương thức. –

Trả lời

24

Chính vì có các chủ đề khác truy cập vào nó. Khi bạn cố gắng sử dụng kích thước bạn nhận được từ qsize(), hàng đợi có thể đã thay đổi. Sẽ tốt hơn nếu tài liệu đọc như sau:

Trả về kích thước của hàng đợi. Lưu ý rằng trong môi trường nhiều luồng, kích thước có thể thay đổi bất kỳ lúc nào, làm cho kích thước này chỉ xấp xỉ kích thước thực tế.

5

Tôi đồng ý rằng 'gần đúng' không phải là lựa chọn rõ ràng nhất của từ nhưng như Ned đề cập họ đang cố gắng chỉ ra rằng đơn giản vì kích thước của hàng đợi tại thời điểm t1 là 7 không có nghĩa là nó sẽ vẫn là kích thước 7 khi bạn đẩy hoặc bật các giá trị sau này.

Vấn đề là giả định rằng kích thước bạn nhận được từ qsize sẽ vẫn chính xác khi bạn đẩy/bật giá trị của hàng đợi đó có thể hoạt động bất ngờ trong môi trường nhiều luồng.

Ví dụ:

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 

Đây là một ví dụ về LBYL "Nhìn trước khi bạn bước nhảy vọt" và đó là nguy hiểm vì tình trạng chủng tộc tiềm năng ở đây khi nhiều chủ đề đang truy cập vào hàng đợi.

Trong trường hợp này bạn nên ủng hộ EAFP hoặc "dễ dàng hơn để yêu cầu sự tha thứ hơn cho phép" và làm như sau:

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

.. hoặc chỉ sử dụng semaphore để đảm bảo rằng hàng đợi có mục nhập. –

+6

Hàng đợi đã được đồng bộ hóa, không thêm nhiều hàng hơn nữa. Sử dụng 'q.get' với một ngoại lệ là cách an toàn nhất để có được một mục. –

Các vấn đề liên quan