Python의 queue.Queue
에서 "task_done() called too many times" 오류가 발생하는 이유는 task_done()
메서드를 get()
으로 가져온 아이템 수보다 더 많이 호출했기 때문입니다.
발생 원리
Queue는 내부적으로 "처리되지 않은 작업 수(unfinished tasks)"를 카운터로 관리합니다.
put()
으로 아이템을 넣을 때마다 카운터가 +1task_done()
을 호출할 때마다 카운터가 -1- 카운터가 0보다 작아지려고 하면 이 오류가 발생
주요 원인들
get() 없이 task_done() 호출
import queue
q = queue.Queue()
q.put("item")
q.task_done() # get()을 하지 않았는데 task_done() 호출 - 오류!
task_done()을 중복 호출
import queue
q = queue.Queue()
q.put("item")
item = q.get()
q.task_done()
q.task_done() # 같은 아이템에 대해 두 번 호출 - 오류!
- 스레드에서 동기화 문제
import queue
import threading
q = queue.Queue()
def worker():
while True:
item = q.get()
# 작업 처리
q.task_done()
q.task_done() # 실수로 두 번 호출
# 여러 스레드가 동시에 task_done()을 호출하는 경우
올바른 사용법
import queue
import threading
q = queue.Queue()
def worker():
while True:
item = q.get()
if item is None:
break
# 작업 처리
print(f"Processing {item}")
q.task_done() # get()한 아이템 하나당 정확히 한 번만 호출
# 작업 추가
for i in range(5):
q.put(f"task-{i}")
# 워커 스레드 시작
thread = threading.Thread(target=worker)
thread.start()
# 모든 작업 완료 대기
q.join() # 모든 task_done()이 호출될 때까지 대기
디버깅 팁
get()
과task_done()
의 호출 횟수가 정확히 일치하는지 확인- 예외 처리 시에도
task_done()
이 빠지지 않도록 try-finally 구문 사용 - 멀티스레딩 환경에서는 각 스레드가 자신이 가져간 아이템에만
task_done()
을 호출하도록 주의
728x90
반응형
'프로그래밍 > Python' 카테고리의 다른 글
[python] uuid 패키지의 uuid1()과 uuid4() 차이점 (0) | 2024.08.23 |
---|---|
[Python] Enum과 Final 상수 비교 분석 (0) | 2024.08.21 |
[python] vscode에서 주로 이용하는 확장 알아보기 (0) | 2024.08.01 |
[python] pytest와 unittest 비교 분석 (0) | 2024.07.27 |
[python] TestCase를 활용한 기본적인 유닛 테스트 작성하기 (0) | 2024.07.21 |