queue --- Một lớp hàng đợi được đồng bộ hóa¶
Source code: Lib/queue.py
Mô-đun queue triển khai hàng đợi nhiều nhà sản xuất, nhiều người tiêu dùng. Nó đặc biệt hữu ích trong lập trình luồng khi thông tin phải được trao đổi một cách an toàn giữa nhiều luồng. Lớp Queue trong mô-đun này triển khai tất cả ngữ nghĩa khóa cần thiết.
Mô-đun này triển khai ba loại hàng đợi, chỉ khác nhau ở thứ tự truy xuất các mục. Trong hàng đợi FIFO, tác vụ đầu tiên được thêm vào sẽ là tác vụ được truy xuất đầu tiên. Trong hàng đợi LIFO, mục được thêm gần đây nhất là mục được truy xuất đầu tiên (hoạt động giống như một ngăn xếp). Với hàng đợi ưu tiên, các mục nhập sẽ được sắp xếp (sử dụng mô-đun heapq) và mục nhập có giá trị thấp nhất sẽ được truy xuất trước tiên.
Trong nội bộ, ba loại hàng đợi đó sử dụng khóa để tạm thời chặn các luồng cạnh tranh; tuy nhiên, chúng không được thiết kế để xử lý việc đăng nhập lại trong một luồng.
Ngoài ra, mô-đun này còn triển khai một loại hàng đợi FIFO "đơn giản", SimpleQueue, việc triển khai cụ thể của nó sẽ cung cấp các đảm bảo bổ sung để đổi lấy chức năng nhỏ hơn.
Mô-đun queue xác định các lớp và ngoại lệ sau:
- class queue.Queue(maxsize=0)¶
Trình xây dựng cho hàng đợi FIFO. maxsize là một số nguyên đặt giới hạn trên cho số lượng mục có thể được đặt trong hàng đợi. Quá trình chèn sẽ chặn khi đạt đến kích thước này cho đến khi các mục trong hàng đợi được sử dụng hết. Nếu maxsize nhỏ hơn hoặc bằng 0 thì kích thước hàng đợi là vô hạn.
- class queue.LifoQueue(maxsize=0)¶
Trình xây dựng cho hàng đợi LIFO. maxsize là một số nguyên đặt giới hạn trên cho số lượng mục có thể được đặt trong hàng đợi. Quá trình chèn sẽ chặn khi đạt đến kích thước này cho đến khi các mục trong hàng đợi được sử dụng hết. Nếu maxsize nhỏ hơn hoặc bằng 0 thì kích thước hàng đợi là vô hạn.
- class queue.PriorityQueue(maxsize=0)¶
Trình xây dựng cho hàng đợi ưu tiên. maxsize là một số nguyên đặt giới hạn trên cho số lượng mục có thể được đặt trong hàng đợi. Quá trình chèn sẽ chặn khi đạt đến kích thước này cho đến khi các mục trong hàng đợi được sử dụng hết. Nếu maxsize nhỏ hơn hoặc bằng 0 thì kích thước hàng đợi là vô hạn.
Các mục có giá trị thấp nhất sẽ được truy xuất trước (mục có giá trị thấp nhất là mục sẽ được
min(entries)trả về). Mẫu điển hình cho các mục là một bộ dữ liệu có dạng:(priority_number, data).Nếu các phần tử data không thể so sánh được thì dữ liệu có thể được gói trong một lớp bỏ qua mục dữ liệu và chỉ so sánh số ưu tiên:
từ các lớp dữ liệu nhập lớp dữ liệu, trường từ việc nhập nhập Bất kỳ @dataclass(thứ tự=True) lớp Ưu tiên: mức độ ưu tiên: int mục: Any=field(so sánh=False)
- class queue.SimpleQueue¶
Trình xây dựng cho hàng đợi FIFO không giới hạn. Hàng đợi đơn giản thiếu chức năng nâng cao như theo dõi tác vụ.
Added in version 3.7.
- exception queue.Empty¶
Ngoại lệ nảy sinh khi
get()(hoặcget_nowait()) không chặn được gọi trên đối tượngQueuetrống.
- exception queue.Full¶
Ngoại lệ nảy sinh khi gọi
put()(hoặcput_nowait()) không chặn trên đối tượngQueueđã đầy.
- exception queue.ShutDown¶
Ngoại lệ xuất hiện khi
put()hoặcget()được gọi trên đối tượngQueueđã bị tắt.Added in version 3.13.
Đối tượng xếp hàng¶
Các đối tượng xếp hàng (Queue, LifoQueue hoặc PriorityQueue) cung cấp các phương thức công khai được mô tả bên dưới.
- Queue.qsize()¶
Trả về kích thước gần đúng của hàng đợi. Lưu ý, qsize() > 0 không đảm bảo rằng get() tiếp theo sẽ không chặn, qsize() < maxsize cũng không đảm bảo rằng put() sẽ không chặn.
- Queue.empty()¶
Trả về
Truenếu hàng đợi trống,Falsenếu không. Nếu trống() trả vềTrue, điều đó không đảm bảo rằng lệnh gọi tiếp theo tới put() sẽ không bị chặn. Tương tự, nếu void() trả vềFalsethì điều đó không đảm bảo rằng lệnh gọi get() tiếp theo sẽ không bị chặn.
- Queue.full()¶
Trả về
Truenếu hàng đợi đầy, nếu không thì trả vềFalse. Nếu full() trả vềTruethì điều đó không đảm bảo rằng lệnh gọi get() tiếp theo sẽ không bị chặn. Tương tự, nếu full() trả vềFalsethì điều đó không đảm bảo rằng lệnh gọi put() tiếp theo sẽ không bị chặn.
- Queue.put(item, block=True, timeout=None)¶
Đặt item vào hàng đợi. Nếu các đối số tùy chọn block là đúng và timeout là
None(mặc định), hãy chặn nếu cần cho đến khi có chỗ trống. Nếu timeout là số dương, nó sẽ chặn tối đa timeout giây và tăng ngoại lệFullnếu không có chỗ trống nào trong thời gian đó. Ngược lại (block là sai), hãy đặt một mục vào hàng đợi nếu ngay lập tức có một vị trí trống, nếu không thì sẽ đưa ra ngoại lệFull(timeout bị bỏ qua trong trường hợp đó).Tăng
ShutDownnếu hàng đợi đã bị tắt.
- Queue.put_nowait(item)¶
Tương đương với
put(item, block=False).
- Queue.get(block=True, timeout=None)¶
Xóa và trả lại một mục từ hàng đợi. Nếu các đối số tùy chọn block là đúng và timeout là
None(mặc định), hãy chặn nếu cần thiết cho đến khi có một mục. Nếu timeout là số dương, nó sẽ chặn tối đa timeout giây và tăng ngoại lệEmptynếu không có mục nào có sẵn trong thời gian đó. Nếu không (block là sai), hãy trả lại một mục nếu có sẵn ngay lập tức, nếu không thì đưa ra ngoại lệEmpty(timeout bị bỏ qua trong trường hợp đó).Trước phiên bản 3.0 trên hệ thống POSIX và đối với tất cả các phiên bản trên Windows, nếu block là đúng và timeout là
Nonethì thao tác này sẽ chuyển sang chế độ chờ liên tục trên khóa cơ bản. Điều này có nghĩa là không có trường hợp ngoại lệ nào có thể xảy ra và đặc biệt là SIGINT sẽ không kích hoạtKeyboardInterrupt.Tăng
ShutDownnếu hàng đợi đã bị tắt và trống hoặc nếu hàng đợi đã bị tắt ngay lập tức.
- Queue.get_nowait()¶
Tương đương với
get(False).
Hai phương pháp được cung cấp để hỗ trợ theo dõi xem các tác vụ trong hàng đợi đã được xử lý hoàn toàn bởi các luồng tiêu dùng daemon hay chưa.
- Queue.task_done()¶
Cho biết rằng một nhiệm vụ được xếp hàng trước đó đã hoàn thành. Được sử dụng bởi các chủ đề tiêu dùng hàng đợi. Đối với mỗi
get()được sử dụng để tìm nạp một tác vụ, một lệnh gọi tiếp theo tớitask_done()sẽ thông báo cho hàng đợi rằng quá trình xử lý tác vụ đã hoàn tất.Nếu một
join()hiện đang bị chặn thì nó sẽ tiếp tục lại khi tất cả các mục đã được xử lý (có nghĩa là đã nhận được lệnh gọitask_done()cho mọi mục đã đượcput()đưa vào hàng đợi).Tăng
ValueErrornếu được gọi nhiều lần hơn số mục được đặt trong hàng đợi.
- Queue.join()¶
Chặn cho đến khi tất cả các mục trong hàng đợi đã được nhận và xử lý.
Số lượng nhiệm vụ chưa hoàn thành sẽ tăng lên bất cứ khi nào một mục được thêm vào hàng đợi. Số lượng giảm xuống bất cứ khi nào một luồng tiêu dùng gọi
task_done()để cho biết rằng mục đó đã được truy xuất và tất cả công việc trên đó đã hoàn tất. Khi số lượng nhiệm vụ chưa hoàn thành giảm xuống 0,join()sẽ mở khóa.
Đang chờ hoàn thành nhiệm vụ¶
Ví dụ về cách chờ hoàn thành các tác vụ được xếp hàng đợi
nhập luồng
hàng đợi nhập khẩu
q = hàng đợi.Queue()
công nhân def():
trong khi Đúng:
mục = q.get()
print(f'Đang làm việc trên {item}')
print(f'Đã hoàn thành {item}')
q.task_done()
# Turn-on luồng công nhân.
threading.Thread(target=worker, daemon=True).start()
# Send ba mươi yêu cầu nhiệm vụ cho nhân viên.
đối với mục trong phạm vi (30):
q.put(mục)
# Block cho đến khi hoàn thành mọi nhiệm vụ.
q.join()
print('Tất cả công việc đã hoàn thành')
Chấm dứt hàng đợi¶
Khi không còn cần thiết, các đối tượng Queue có thể được thu gọn lại cho đến khi trống hoặc chấm dứt ngay lập tức bằng cách tắt máy cứng.
- Queue.shutdown(immediate=False)¶
Đặt phiên bản
Queuevào chế độ tắt máy.Hàng đợi không thể phát triển được nữa. Các cuộc gọi trong tương lai tới
put()sẽ tăngShutDown. Những người gọiput()hiện bị chặn sẽ được bỏ chặn và sẽ gọiShutDowntrong chuỗi bị chặn trước đây.Nếu immediate là sai (mặc định), hàng đợi có thể được kết thúc bình thường bằng các lệnh gọi
get()để trích xuất các tác vụ đã được tải.Và nếu
task_done()được gọi cho mỗi nhiệm vụ còn lại,join()đang chờ xử lý sẽ được bỏ chặn bình thường.Khi hàng đợi trống, các lệnh gọi tới
get()trong tương lai sẽ tăngShutDown.Nếu immediate đúng, hàng đợi sẽ bị chấm dứt ngay lập tức. Hàng đợi được rút hết hoàn toàn trống và số lượng nhiệm vụ chưa hoàn thành sẽ giảm đi theo số lượng nhiệm vụ đã được rút hết. Nếu nhiệm vụ chưa hoàn thành bằng 0, người gọi
join()sẽ được bỏ chặn. Ngoài ra, những người gọi bị chặn củaget()sẽ được bỏ chặn và sẽ gọiShutDownvì hàng đợi trống.Hãy thận trọng khi sử dụng
join()với immediate được đặt thành true. Điều này sẽ bỏ chặn sự tham gia ngay cả khi không có công việc nào được thực hiện đối với các tác vụ, vi phạm tính bất biến thông thường khi tham gia hàng đợi.Added in version 3.13.
Đối tượng SimpleQueue¶
Các đối tượng SimpleQueue cung cấp các phương thức công khai được mô tả bên dưới.
- SimpleQueue.qsize()¶
Trả về kích thước gần đúng của hàng đợi. Lưu ý, qsize() > 0 không đảm bảo rằng get() tiếp theo sẽ không bị chặn.
- SimpleQueue.empty()¶
Trả về
Truenếu hàng đợi trống,Falsenếu không. Nếu trống() trả vềFalse, điều đó không đảm bảo rằng lệnh gọi tiếp theo tới get() sẽ không bị chặn.
- SimpleQueue.put(item, block=True, timeout=None)¶
Đặt item vào hàng đợi. Phương thức này không bao giờ chặn và luôn thành công (ngoại trừ các lỗi tiềm ẩn ở mức độ thấp như không phân bổ được bộ nhớ). Các đối số tùy chọn block và timeout bị bỏ qua và chỉ được cung cấp để tương thích với
Queue.put().Phương pháp này có triển khai C được đăng ký lại. Nghĩa là, cuộc gọi
put()hoặcget()có thể bị gián đoạn bởi một cuộc gọiput()khác trong cùng một chuỗi mà không gây bế tắc hoặc làm hỏng trạng thái bên trong hàng đợi. Điều này làm cho nó thích hợp để sử dụng trong các hàm hủy như phương thức__del__hoặc lệnh gọi lạiweakref.
- SimpleQueue.put_nowait(item)¶
Tương đương với
put(item, block=False), được cung cấp để tương thích vớiQueue.put_nowait().
- SimpleQueue.get(block=True, timeout=None)¶
Xóa và trả lại một mục từ hàng đợi. Nếu các đối số tùy chọn block là đúng và timeout là
None(mặc định), hãy chặn nếu cần thiết cho đến khi có một mục. Nếu timeout là số dương, nó sẽ chặn tối đa timeout giây và tăng ngoại lệEmptynếu không có mục nào có sẵn trong thời gian đó. Nếu không (block là sai), hãy trả lại một mục nếu có sẵn ngay lập tức, nếu không thì đưa ra ngoại lệEmpty(timeout bị bỏ qua trong trường hợp đó).
- SimpleQueue.get_nowait()¶
Tương đương với
get(False).
Xem thêm
- Lớp
multiprocessing.Queue Một lớp hàng đợi để sử dụng trong ngữ cảnh đa xử lý (chứ không phải đa luồng).
collections.deque là một triển khai thay thế của hàng đợi không giới hạn với các hoạt động append() và popleft() nguyên tử nhanh không yêu cầu khóa và cũng hỗ trợ lập chỉ mục.