SSAMKO의 개발 이야기

[python] 병렬 작업 처리 | 비동기 처리 - threading, asyncio 본문

Python

[python] 병렬 작업 처리 | 비동기 처리 - threading, asyncio

SSAMKO 2021. 2. 17. 20:45
반응형

회사에서 AI모듈 패키징을 하며, 여러 대의 GPU를 효율적으로 사용하는 방법에 대한 고민이 있었다.

각각의 아이템들에 특정 gpu index를 부여해서, 해당 gpu에서 작업하도록 하는 방법을 사용중이었는데, (Round Robin Load Balancing Algorithm과 유사)

기존 multi GPU 활용방법

이 방법은 놀고 있는 gpu가 있어도 특정 gpu에 업무가 몰릴 수 있다는 단점이 있었다.

 

그래서 각 아이템에 gpu_index를 부여하는 대신, 아이템이 업로드 되면 대기중인 gpu를 찾아서 해당 아이템의 처리를 하게 하는 방식으로 로직을 다시 작성할 필요가 있었다. (Least Connections Load Balancing Algorithm과 유사)

 

(물론, 이 방법을 처음부터 생각하지 못한 것은 아니었지만, 구현이 좀 더 복잡해서 미뤄뒀던 것이다.)

 

생각해낸 해결책은

감독Director과 작업자Worker를 두고, 

감독이 1) 처리할 아이템이 있는지 확인하고, 2) 대기중인 GPU가 있다면, 3) Worker를 생성해서 해당 아이템을 처리하도록 한다. 

그리고 4) Worker가 작업이 끝났는지 확인해서 작업이 끝난 Worker는 삭제한다.

 

작업자Worker는 생성되면 1) 아이템을 처리하고, 처리가 완료되면 2) 완료 상태로 바꾼다.

 

Director와 Worker의 관계도

 

이 로직을 구현하기 위해서는 비동기 처리가 필요했다.

 

처음엔 이 비동기 처리를 위해서 asyncio를 이용했다. 

하지만, 이 asyncio로 비동기 처리는 됐지만, await로 각 비동기 프로세스들이 종료되기를 기다리는 부분이 있어야 한다는 문제가 있었다.

 

Director는 계속해서 본인의 할 일을 하고,

Worker는 자기 작업을 마치고 빠지면 되는 것인데,

Director가 각 Worker들의 작업이 다 끝나길 기다리면 이 로직이 성립되지 않는 것이었다.

 

그래서 다른 방법을 고민하다가 각각의 처리를 개별 thread로 처리하는 방안을 생각해냈다.

Worker클래스를 threading.Thread의 하위 클래스로 만들어서 thread를 실행시키고, 실행이 끝난 Worker는 소멸시키는 방법이다.

 

이 방법을 적용하니 Director는 메인 thread로 돌고, 각각의 Worker들이 독립적인 sub thread로 작업을 하면서,

원하던대로 작동하게 되었다.

 

이런 처리가 필요한 상황이 많을 것 같아 범용 모듈로 만들었다.

스크립트가 궁금한 사람은 아래 링크에서 확인하기 바랍니다. 

 

더불어 더 좋은 아이디어나 개선점이 있다면 알려주시기 바랍니다 :)

 

github.com/teacherSsamko/DirectorWorker

 

teacherSsamko/DirectorWorker

Director and Worker. using thread. Contribute to teacherSsamko/DirectorWorker development by creating an account on GitHub.

github.com

thread에 관해서 궁금하신 분은 아래 위키피디아를 확인해보세요

ko.wikipedia.org/wiki/%EC%8A%A4%EB%A0%88%EB%93%9C_(%EC%BB%B4%ED%93%A8%ED%8C%85)

 

스레드 (컴퓨팅) - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 두 개의 스레드를 실행하고 있는 하나의 프로세스. 스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으

ko.wikipedia.org

 

반응형
Comments