프로그래밍/Python 파이썬
Python - 기존 코드 병렬 처리 - 멀티쓰레드(Multi Thread)
Heidong
2023. 10. 20. 23:50
반응형
목적
사용중이던 메소드 하나가 동기 방식이여서 요청을 보내고 기다리는 식을 반복문으로 감싼터라 시간이 매우 오래 걸렸다.
이를 비동기 방식으로 실행 한다면 엄청난 시간 절약이 될 것이라서 코드 변경을 하려고 한다.
문제 발생
비동기 처리를 위해서 여러가지 파이썬 라이브러리를 찾던중 가장 최근의 라이브러리인 asyncio를 선택했었다.
하지만 내가 보내는 요청은 requests를 사용하는 라이브러리를 가져와서 사용하는 것이라서 해당 패키지를 뜯어서 고치지 않는이상 asyncio를 사용할 수 없었다.
asyncio를 사용하기 위해서는 요청을 보내는 코드에 손을 봐야 했었다.
해결
내가 원하는 프로그램 구동 방식은 해당 메소드 그 자체를 여러번 동시에 실행하는것 즉 메소드 그 자체를 비동기로 돌리는것
이건 즉 멀티 쓰레딩을 통해서 해결 할 수 있었다.
예제 코드
from concurrent.futures import ThreadPoolExecutor
# Define a simple function to be executed concurrently
def square(x):
return x * x
if __name__ == "__main__":
# Create a ThreadPoolExecutor with, for example, 2 worker threads
with ThreadPoolExecutor(max_workers=2) as executor:
# Submit tasks for execution
results = []
# Submit multiple tasks concurrently
for i in range(1, 6):
future = executor.submit(square, i)
results.append(future)
# Wait for all tasks to complete and get the results
for future in results:
result = future.result()
print(f"Result: {result}")
square 메소드를 멀티 쓰레드하는 모습이다.
실제 수정 코드
results = []
with futures.ThreadPoolExecutor(max_workers = max_workers) as executor:
print(f"max worker : {executor._max_workers}")
# start Thread work
try:
for check_data in data_list:
t = executor.submit(fetch, check_data)
results.append(t)
# for stop delay
time.sleep(0.1)
except KeyboardInterrupt as e:
print(f"KeyboardInterrupt : cancel by user")
# clear console
os.system('cls') # window
os.system('clear') # linux
# wait for running tasks
executor.shutdown(wait=True)
# put data
for f in futures.as_completed(results):
out = f.result()
if out:
new_list.append(out)
fetch() 라는 메소드를 멀티 쓰레딩 하는 코드로 바꾸었다.
여기서 포인트는 멀티 쓰레드 종료 기능을 넣은 것.
ctrl + c 를 누르게 되면 KeyboardInterrupt 에러가 발생하니 해당 에러가 발생할 경우
반복문을 빠져나오고 그동안 작업한 내용은 저장을 한다.
무한 루프에 빠지게 되면 속도가 너무 빨라 취소 단축키가 안먹히니 적당히 sleep을 준다.
하지만 반복문은 빠져 나왔어도 현재 실행중인 스레드가 남아 있기때문에
executor.shutdown(wait=True)
해당 메소드와 인자로 각 스레드가 실행중인 작업까지는 기다린다.
반응형