[python] Concurrent.futures 모듈을 활용한 병렬처리 - 1

건너별·2022년 5월 19일
0

python

목록 보기
7/12

GIL(Global internal lock)로 인한 제약

  • python에서는 항상 한 번에 하나의 스레드만 실행됨
    - 두 개 이상의 스레드가 동시에 실행될 때 두 개 이상의 스레드가 하나의 자원을 동시에 액세스할 때 발생할 수 있는 문제점을 방지하기 위함
  • 이 때문에 멀티스레드를 통한 분산처리는 파이썬 내에서 의미가 없음
  • 이 때문에 분산처리를 하려면 멀티스레딩을 해야 하는데, 이 또한 병목이 되는 일

Concurrent.futures 모듈

  • 별도 규격의 스레드 객체를 작성하지 않고 함수 호출을 객체화
  • 이를 통해 다른 프로세스에서 실행할 수 있게 해줌
  • Executer 클래스가 핵심 :
    - ThreadPoolExecutor : 멀티스레딩
    • ProcessPoolExector : 멀티프로세싱

Future

  • 처리되는 실행 단위들의 완료 여부를 확인할 수 있는 객체
  • 확인 후 개체 내 작업이 완료되기를 기다리거나, 미리 콜백을 넘겨놓아둘 수 있음
  • 호출해야 할 함수와 그에 전달될 인자들을 executor에 넘겨주는 것으로 시작
  • 이 때 해당 메소드를 바로 리턴하게 되는데 이것이 future 객체

Executor

  • 초기화 시에 몇 개의 worker가 사용될 것인지를 정해주면 전달되는 작업들을 큐에 넣음
  • worker pool에서 사용 가능한 worker로 작업을 처리

submit(fn, *args, **kwargs)

  • 함수 fn 에 대해 주어진 인자들을 전달하여 실행할 수 있는 Future 객체를 리턴
  • 해당 함수는 호출 즉시 스케쥴링
with ThreadPoolExcutor(max_workers=1) as executor:
    future = executor.submit(pow, 323, 1235)
    print(future.result())

map(func, *iterables, timeout=None)

  • 일반함수 map과 동일하지만, 각 호출은 병렬적으로 일어남
  • 만약 timeout 값이 지정된 경우, 기간 내에 완료되지 않은 호출이 있으면 TimeoutError가 일어남
  • 입력데이터와 동작함수를 짝지어서 바로 스케줄링하도록 함
  • map함수는 이터레이터를 리턴하는데, 이는 각 개별 작업이 도잇에 실행된 후 먼저 종료된 작업부터 내놓는 리턴값을 내놓게 됨

shutdown(wait=True)

  • executor 에 종료 시그널을 보냄
  • 시그널을 받은 executor는 모든 future에 대해 리소스 정리
  • 강제 shutdown을 피하기 위해 with 구문 내에서 사용
import shutil
with ThreadPoolExcutor(max_workers=4) as e:
    e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
    e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
    e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
    e.submit(shutil.copy, 'src4.txt', 'dest4.txt')

Reference

profile
romantic ai developer

0개의 댓글