# `queue` — 동기화된 큐 클래스

소스 코드: Lib/queue.py

`queue` 모듈은 다중 생산자, 다중 소비자 큐를 구현합니다. 정보가 여러 스레드 간에 안전하게 교환되어야 할 때 스레드 프로그래밍에서 특히 유용합니다. 이 모듈의 `Queue` 클래스는 필요한 모든 로킹 개념을 구현합니다.

The module implements three types of queue, which differ only in the order in which the entries are retrieved. In a FIFO queue, the first tasks added are the first retrieved. In a LIFO queue, the most recently added entry is the first retrieved (operating like a stack). With a priority queue, the entries are kept sorted (using the `heapq` module) and the lowest valued entry is retrieved first.

내부적으로, 이러한 3가지 유형의 큐는 록을 사용하여 경쟁 스레드를 일시적으로 블록합니다; 그러나, 스레드 내에서의 재진입을 처리하도록 설계되지는 않았습니다.

또한, 이 모듈은 “간단한” FIFO 큐 유형인 `SimpleQueue`를 구현합니다. 이 특정 구현은 작은 기능을 포기하는 대신 추가 보장을 제공합니다.

`queue` 모듈은 다음 클래스와 예외를 정의합니다:

class queue.Queue(maxsize=0)

  FIFO 큐의 생성자. maxsize는 큐에 배치할 수 있는 항목 수에 대한 상한을 설정하는 정수입니다. 일단, 이 크기에 도달하면, 큐 항목이 소비될 때까지 삽입이 블록 됩니다. maxsize가 0보다 작거나 같으면, 큐 크기는 무한합니다.

class queue.LifoQueue(maxsize=0)

  LIFO 큐의 생성자. maxsize는 큐에 배치할 수 있는 항목 수에 대한 상한을 설정하는 정수입니다. 일단, 이 크기에 도달하면, 큐 항목이 소비될 때까지 삽입이 블록 됩니다. maxsize가 0보다 작거나 같으면, 큐 크기는 무한합니다.

class queue.PriorityQueue(maxsize=0)

  우선순위 큐의 생성자. maxsize는 큐에 배치할 수 있는 항목 수에 대한 상한을 설정하는 정수입니다. 일단, 이 크기에 도달하면, 큐 항목이 소비될 때까지 삽입이 블록 됩니다. maxsize가 0보다 작거나 같으면, 큐 크기는 무한합니다.

  The lowest valued entries are retrieved first (the lowest valued entry is the one that would be returned by `min(entries)`). A typical pattern for entries is a tuple in the form: `(priority_number, data)`.

  data 요소를 비교할 수 없으면, 데이터는 데이터 항목을 무시하고 우선순위 숫자만 비교하는 클래스로 감쌀 수 있습니다:

      from dataclasses import dataclass, field
      from typing import Any

      @dataclass(order=True)
      class PrioritizedItem:
          priority: int
          item: Any=field(compare=False)

class queue.SimpleQueue

  상한 없는 FIFO 큐의 생성자. 단순 큐에는 작업 추적과 같은 고급 기능이 없습니다.

  버전 3.7에 추가.

exception queue.Empty

  비 블로킹 `get()`(또는 `get_nowait()`)이 비어있는 `Queue` 객체에 호출될 때 발생하는 예외.

exception queue.Full

  비 블로킹 `put()`(또는 `put_nowait()`)이 가득 찬 `Queue` 객체에 호출될 때 발생하는 예외.

## 큐 객체

큐 객체(`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)

  Put item into the queue. If optional args block is true and timeout is `None` (the default), block if necessary until a free slot is available. If timeout is a positive number, it blocks at most timeout seconds and raises the `Full` exception if no free slot was available within that time. Otherwise (block is false), put an item on the queue if a free slot is immediately available, else raise the `Full` exception (timeout is ignored in that case).

Queue.put_nowait(item)

  Equivalent to `put(item, block=False)`.

Queue.get(block=True, timeout=None)

  큐에서 항목을 제거하고 반환합니다. 선택적 인자 block이 참이고 timeout이 `None`(기본값)이면, 항목이 사용 가능할 때까지 필요하면 블록합니다. timeout이 양수면, 최대 timeout 초 동안 블록하고 그 시간 내에 사용 가능한 항목이 없으면 `Empty` 예외가 발생합니다. 그렇지 않으면 (block이 거짓), 즉시 사용할 수 있는 항목이 있으면 반환하고, 그렇지 않으면 `Empty` 예외를 발생시킵니다 (이때 timeout은 무시됩니다).

  Prior to 3.0 on POSIX systems, and for all versions on Windows, if block is true and timeout is `None`, this operation goes into an uninterruptible wait on an underlying lock. This means that no exceptions can occur, and in particular a SIGINT will not trigger a `KeyboardInterrupt`.

Queue.get_nowait()

  `get(False)`와 동등합니다.

큐에 넣은 작업이 데몬 소비자 스레드에 의해 완전히 처리되었는지를 추적하는 것을 지원하는 두 가지 메서드가 제공됩니다.

Queue.task_done()

  앞서 큐에 넣은 작업이 완료되었음을 나타냅니다. 큐 소비자 스레드에서 사용됩니다. 작업을 꺼내는 데 사용되는 `get()`마다, 후속 `task_done()` 호출은 작업에 대한 처리가 완료되었음을 큐에 알려줍니다.

  `join()`이 현재 블로킹 중이면, 모든 항목이 처리되면 (큐로 `put()` 된 모든 항목에 대해 `task_done()` 호출이 수신되었음을 뜻합니다) 재개됩니다.

  큐에 있는 항목보다 더 많이 호출되면 `ValueError`를 발생시킵니다.

Queue.join()

  큐의 모든 항목을 꺼내서 처리할 때까지 블록합니다.

  The count of unfinished tasks goes up whenever an item is added to the queue. The count goes down whenever a consumer thread calls `task_done()` to indicate that the item was retrieved and all work on it is complete. When the count of unfinished tasks drops to zero, `join()` unblocks.

큐에 포함된 작업이 완료될 때까지 대기하는 방법의 예:

    import threading
    import queue

    q = queue.Queue()

    def worker():
        while True:
            item = q.get()
            print(f'Working on {item}')
            print(f'Finished {item}')
            q.task_done()

    # Turn-on the worker thread.
    threading.Thread(target=worker, daemon=True).start()

    # Send thirty task requests to the worker.
    for item in range(30):
        q.put(item)

    # Block until all tasks are done.
    q.join()
    print('All work completed')

## SimpleQueue 객체

`SimpleQueue` 객체는 아래에서 설명하는 공용 메서드를 제공합니다.

SimpleQueue.qsize()

  큐의 대략의 크기를 돌려줍니다. 주의하십시오, qsize() > 0 은 후속 get()이 블록 되지 않는다는 것을 보장하지 않습니다.

SimpleQueue.empty()

  Return `True` if the queue is empty, `False` otherwise. If empty() returns `False` it doesn’t guarantee that a subsequent call to get() will not block.

SimpleQueue.put(item, block=True, timeout=None)

  item을 큐에 넣습니다. 이 메서드는 결코 블록하지 않고 항상 성공합니다 (메모리 할당 실패와 같은 잠재적 저수준 에러 제외). 선택적 인자 block과 timeout은 무시되고 `Queue.put()`과의 호환성을 위해서만 제공됩니다.

  CPython 구현 상세: This method has a C implementation which is reentrant. That is, a `put()` or `get()` call can be interrupted by another `put()` call in the same thread without deadlocking or corrupting internal state inside the queue. This makes it appropriate for use in destructors such as `__del__` methods or `weakref` callbacks.

SimpleQueue.put_nowait(item)

  Equivalent to `put(item, block=False)`, provided for compatibility with `Queue.put_nowait()`.

SimpleQueue.get(block=True, timeout=None)

  큐에서 항목을 제거하고 반환합니다. 선택적 인자 block이 참이고 timeout이 `None`(기본값)이면, 항목이 사용 가능할 때까지 필요하면 블록합니다. timeout이 양수면, 최대 timeout 초 동안 블록하고 그 시간 내에 사용 가능한 항목이 없으면 `Empty` 예외가 발생합니다. 그렇지 않으면 (block이 거짓), 즉시 사용할 수 있는 항목이 있으면 반환하고, 그렇지 않으면 `Empty` 예외를 발생시킵니다 (이때 timeout은 무시됩니다).

SimpleQueue.get_nowait()

  `get(False)`와 동등합니다.

더 보기

`multiprocessing.Queue` 클래스

  (다중 스레드 대신) 다중 프로세스 문맥에서 사용하기 위한 큐 클래스.

`collections.deque`는 록을 필요로하지 않고 인덱싱을 지원하는 빠른 원자적 `append()`와 `popleft()` 연산을 제공하는 크기 제한 없는 큐의 대체 구현입니다.