queue
다중 생산, 다중 소비자 큐의 구현. 멀티스레드를 고려한 큐를 구현해놓은 모듈. 내부적으로 locking을 지원하여 여러 스레드가 동시에 데이터를 추가하거나 삭제할 수 있다. 기본적인 큐의 형태를 그대로 구현하였다.
클래스
Queue(maxsize=0)
상한을 정해놓은 큐. 상한에 도달하면 삽입을 막는다. 0보다 작거나 같은 값을 넣어주면 무한한 크기의 큐.
LifoQueue(maxsize=0)
LIFO(Last in First out) == 스택. 나머지는 위와 동일
PriorityQueue(maxisze=0)
우선순위 큐. 낮은값을 가지는 항목을 먼저 꺼냄. 일반적으로 (priority,data)형태로 삽입
SimpleQueue()
상한이 없는 큐. 고급기능이 없는 단순한 형태
메소드
qsize()
- 큐의 대략의 크기를 반환.
- 0보다 크다고 get()이 가능하다는 것을 보장하지 않고, maxsize보다 작더라도 put()이 가능하다고 보장하지 않는다. 다중 스레드 환경에서의 동작을 고려해 구현된 상태이므로 그런듯 하다.
empty()
- 비어있으면 True, 아니면 False
- qsize()와 동일하게 put, get에 대한 동작을 보장하지 않음.
put(item, block=True, timeout=None)
- item을 큐에 삽입
- block=True면 큐에 자리가 날때까지 block.
- timeout이 양수면 최대 timeout초 동안 block하고 빈자리가 나지 않으면 full 예외 발생.
- block=False면 슬롯이 없을때 block이 아니라 바로 full 예외 발생.
put_nowait(item)
- put(item,block=False)와 동일.
get(block=True, timeout=None)
- 큐에서 항목을 제거하고 반환.
- block=True면 큐에 가져올 데이터가 있을때 까지 block
- timeout이 양수면 최대 timeout초 동안 block하고 데이터가 들어오지 않으면 empty 예외 발생.
- block=False면 데이터가 없을때 바로 empty 예외 발생.
get_nowait()
full()
- 여기서부터는 SimpleQueue에는 없는 메소드
- 가득 차면 True, 아니면 False.
- get, put에 대한 동작을 보장하지 않음.
task_done()
- 앞서 큐에 넣은 작업이 완료되었음을 나타냄. 큐 소비자 스레드에서 사용. get() 마다 task_done() 호출은 작업에 대한 처리가 완료됨을 큐에 알려줌
join()
- 큐의 모든 항목을 꺼내서 처리할 때까지 block.
- 소비자 스레드가 task_done()을 호출해서 항목을 꺼내고 작업이 모두 완료되었음을 나타낼때마다 카운트가 내려가며 0으로 떨어지면 block 해제
- 스레드를 실행시키는 함수에서 join을 사용하면 스레드의 동작이 끝나기 전에 해당 함수가 끝나는 것을 방지함.
import threading
import queue
q = queue.Queue()
def worker():
while True:
item = q.get()
print(item)
q.task_done()
threading.Thread(target=worker, daemon=True).start()
for item in range(10):
q.put(item)
q.join()
print('done')