ThreadPool | ThreadPool | ThreadPoolExecutor | |
생성쓰레드 수 | 수동 Thread 1 = Task 1개 | 파라미터로 지정가능 디폴트=(논리CPU수 + 4) |
파라미터로 지정가능 디폴트=(논리CPU수 + 4) |
최적의 용도 | 적은 수로 동시에 실행이 필요한 경우 | 모든 쓰레드가 동시에 실행되지는 않고 비어 있거나 I/O 등의 기다림이 있어 양보된 쓰레드에 실행되게 된다. 같은 태스크 내용으로 파라미터만 달리하여 많은 수의 쓰레드를 실행하는 경우. |
모든 쓰레드가 동시에 실행되지는 않고 비어 있거나 I/O 등의 기다림이 있어 양보된 쓰레드에 실행되게 된다. 같은 태스크 내용으로 파라미터만 달리하여 많은 수의 쓰레드를 실행하는 경우. |
결과의 리턴 | 불가능 | 가능 | 가능 |
취소기능 | 불가능 | 불가능 | 실행되기 전의 태스크에 한해 가능 |
※ ThreadPool 과 ThreadPoolExecutor 는 기본적으로 같은 기능이나 ThreadPoolExecutor 에 약간의 기능이 추가
Thread 의 코드 예
from threading import Thread # 태스크 함수 def task(value): # 여기에 작업을 기술 ... # ... # 작업 끝 print(f'.done {value}') if __name__ == '__main__': # 0...19 의 파라미터를 같는 20개의 쓰레드를 생성 threads = [Thread(target=task, args=(i,)) for i in range(20)] # 모든 쓰레드 시작 for thread in threads: thread.start() # 모든 쓰레드가 종료되기까지 기다리기 for thread in threads: thread.join() # report that all tasks are completed print('Done') |
ThreadPool 의 코드 예
from multiprocessing.pool import ThreadPool # 태스크 함수 def task(value): # 여기에 작업을 기술 ... # ... # 작업 끝 # 필요시 리턴값을 반환 return value if __name__ == '__main__': # 디폴트 수의 쓰레드의 풀을 생성 -> 지정 ThreadPool(processes=10) with ThreadPool() as pool: # 하나의 함수에 0...999 의 파라미터를 같는 100개의 태스크를 발행 # 같은 함수에 다른 파라미터만 전달할 경우 map(함수명, 리스트(파라미터)) for result in pool.map(task, range(100)): # 결과를 처리 # 결과는 0..99 의 실행순서대로 출력 print(f'>got {result}') # 모든 태스크가 끝남 print('Done') |
# 독립적인 태스크를 호출시의 샘플 if __name__ == '__main__': pool = ThreadPool() # apply 를 사용 -> task 가 끝나지 전까지 호출측의 main 쓰레드는 블록이 된다. try: result = pool.apply(task, args=(10,)) # 리턴값 확인 print(f'Main got: {result}') except Exception as e: print(f'Failed with: {e}') # with 를 사용하지 않았음으로 명시적으로 닫아줘야 함. pool.close() |
ThreadPoolExecutor 의 코드 예
import concurrent.futures def task(value): # ... return value if __name__ == '__main__': # 쓰레드 수를 지정하는 경우 -> concurrent.futures. ThreadPoolExecutor(max_workers=10) with concurrent.futures.ThreadPoolExecutor() as exe: # (1) submit 을 이용한 태스크의 발행 # 혹은 future = exe.submit(task, arg1, arg2, ...) 의 형태로 단수 실행도 가능 futures = [exe.submit(task, i) for i in range(50)] # 블록되지 않기 때문 여기에 다른 실행코드를 넣어도 됨 # 모든 태스크의 종료를 기다림 # 단수 쓰레드의 경우 result = future.result(timeout=5) 로 결과를 받음. # 결과는 발행순서 관계없이 빨리 끝나는 대로 리턴 for future in concurrent.futures.as_completed(futures): print(f'>got {future.result}') # 발생순서대로 결과값을 받고 싶을 경우는 # for future in futures: # print(future.result()) # (2) (1)과 같은 작업이지만 map 을 이용하여 파라미터만 바뀌는 반복적인 태스크의 발행 for result in exe.map(task, range(50)): # 실행이 끝나기를 기다리고 결과를 받음 print(f'>got {result}') # report that all tasks are completed print('Done') |
'data science > python' 카테고리의 다른 글
Redis Pub/Sub (1) | 2024.09.09 |
---|---|
threading / multiprocessing / asyncio (0) | 2024.05.02 |
image byte 데이터 <-> numpy string (0) | 2024.04.29 |
two list -> dict (0) | 2024.02.27 |
문자열 리스트 조작 (0) | 2024.02.02 |