очередь — Класс синхронизированной очереди
Исходный код: Lib/queue.py
Модуль queue реализует очереди с множественными производителями и потребителями. Он особенно полезен в многопоточных программах, когда информация должна безопасно обмениваться между несколькими потоками. Класс Queue в этом модуле реализует все необходимые семантики блокировки. Он зависит от наличия поддержки потоков в Python; см. модуль threading.
Модуль реализует три типа очередей, которые различаются только порядком извлечения элементов. В очереди FIFO (первым вошел, первым вышел) первые добавленные задачи извлекаются первыми. В очереди LIFO (последним вошел, первым вышел) последняя добавленная запись извлекается первой (работает как стек). В приоритетной очереди записи сохраняются отсортированными (используя модуль heapq) и первая извлекается запись с наименьшим значением.
Внутренне модуль использует блокировки для временного блокирования конкурирующих потоков; однако он не предназначен для обработки повторного входа в один и тот же поток.
Модуль queue определяет следующие классы и исключения:
-
class queue.Queue(maxsize=0) -
Конструктор для очереди FIFO. maxsize — целое число, устанавливающее верхний предел количества элементов, которые могут быть помещены в очередь. Вставка будет блокироваться, когда этот размер будет достигнут, до тех пор, пока элементы очереди не будут потреблены. Если maxsize меньше или равно нулю, размер очереди бесконечен.
-
class queue.LifoQueue(maxsize=0) -
Конструктор для очереди LIFO. maxsize — целое число, устанавливающее верхний предел количества элементов, которые могут быть помещены в очередь. Вставка будет блокироваться, когда этот размер будет достигнут, до тех пор, пока элементы очереди не будут потреблены. Если maxsize меньше или равно нулю, размер очереди бесконечен.
-
class queue.PriorityQueue(maxsize=0) -
Конструктор для приоритетной очереди. maxsize — целое число, устанавливающее верхний предел количества элементов, которые могут быть помещены в очередь. Вставка будет блокироваться, когда этот размер будет достигнут, до тех пор, пока элементы очереди не будут потреблены. Если maxsize меньше или равно нулю, размер очереди бесконечен.
Первыми извлекаются записи с наименьшим значением (запись с наименьшим значением — это запись, возвращаемая
sorted(list(entries))[0]). Типичная структура для записей — кортеж в формате:(priority_number, data).
-
exception queue.Empty -
Исключение, генерируемое при вызове неблокирующего
get()(илиget_nowait()) для объектаQueue, который пуст.
-
exception queue.Full -
Исключение, генерируемое при вызове неблокирующего
put()(илиput_nowait()) для объектаQueue, который полон.
1. Объекты очереди
Объекты очереди (Queue, LifoQueue или PriorityQueue) предоставляют описанные ниже публичные методы.
-
Queue.qsize() -
Возвращает приблизительный размер очереди. Обратите внимание, что qsize() > 0 не гарантирует, что последующий get() не заблокируется, а qsize() < maxsize не гарантирует, что put() не заблокируется.
-
Queue.empty() -
Возвращает
True, если очередь пуста,False, в противном случае. Если empty() возвращаетTrue, это не гарантирует, что последующий вызов put() не заблокируется. Аналогично, если empty() возвращаетFalse, это не гарантирует, что последующий вызов get() не заблокируется.
-
Queue.full() -
Возвращает
True, если очередь полна,False, в противном случае. Если full() возвращаетTrue, это не гарантирует, что последующий вызов get() не заблокируется. Аналогично, если full() возвращаетFalse, это не гарантирует, что последующий вызов put() не заблокируется.
-
Queue.put(item, block=True, timeout=None) -
Поместить item в очередь. Если необязательный аргумент block имеет значение true и timeout равен
None, заблокировать, если необходимо, пока не освободится место. Если timeout — положительное число, блокируется не более чем на timeout секунд и генерируется исключениеFull, если место не освободилось в течение этого времени. В противном случае (block имеет значение false), поместить элемент в очередь, если место сразу же доступно, иначе сгенерировать исключениеFull(timeout игнорируется в этом случае).
-
Queue.put_nowait(item) -
Эквивалентно
put(item, False).
-
Queue.get(block=True, timeout=None) -
Удалить и вернуть элемент из очереди. Если необязательный аргумент block имеет значение true и timeout равен
None, заблокировать, если необходимо, пока не появится элемент. Если timeout — положительное число, блокируется не более чем на timeout секунд и генерируется исключениеEmpty, если элемент не появился в течение этого времени. В противном случае (block имеет значение false), вернуть элемент, если он сразу же доступен, иначе сгенерировать исключениеEmpty(timeout игнорируется в этом случае).
-
Queue.get_nowait() -
Эквивалентно
get(False).
Предлагаются два метода для отслеживания того, были ли задачи, помещенные в очередь, полностью обработаны потоками-потребителями демонов.
-
Queue.task_done() -
Указывает, что задача, ранее помещенная в очередь, завершена. Используется потоками-потребителями очереди. Для каждого вызова
get()для извлечения задачи последующий вызовtask_done()сообщает очереди, что обработка задачи завершена.Если
join()в настоящее время заблокирован, он возобновится, когда все элементы будут обработаны (то есть вызовtask_done()был получен для каждого элемента, который былput()в очередь).Возбуждает
ValueError, если вызов выполнен больше раз, чем было помещено элементов в очередь.
-
Queue.join() -
Блокируется до тех пор, пока все элементы в очереди не будут извлечены и обработаны.
Счетчик незавершенных задач увеличивается при добавлении элемента в очередь. Счетчик уменьшается всякий раз, когда поток-потребитель вызывает
task_done(), чтобы указать, что элемент был извлечен и вся работа над ним завершена. Когда счетчик незавершенных задач падает до нуля,join()разблокируется.
Пример того, как дождаться завершения задач в очереди:
def worker():
while True:
item = q.get()
if item is None:
break
do_work(item)
q.task_done()
q = queue.Queue()
threads = []
for i in range(num_worker_threads):
t = threading.Thread(target=worker)
t.start()
threads.append(t)
for item in source():
q.put(item)
# block until all tasks are done
q.join()
# stop workers
for i in range(num_worker_threads):
q.put(None)
for t in threads:
t.join()
См. также
-
Classmultiprocessing.Queue - Класс очереди для использования в контексте многопроцессорной (а не многопоточной) обработки.
collections.deque — альтернативная реализация неограниченных очередей с быстрыми атомными операциями append() и popleft(), которые не требуют блокировки.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/queue.html