일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- python
- typescript
- 개발자
- css
- 느린 서버
- iframe
- 스타트업
- 구로 디지털 단지 사무실
- 테드스페이스
- PM
- JS
- javascript
- 2인 사무실
- select tag
- ai로 앱 만들기
- select css
- 구로 공유 오피스
- 동료리뷰
- Regexp
- React
- html
- 리더
- turborepo
- Domination Game
- Django
- 공유 오피스
- 좋은 리더란
- multiprocessing
- XFrameOptions
- 빠른 서버
- Today
- Total
개발하는 일상
python multiprocessing 으로 병렬 작업하기(Django 서버 동시에 여러개 켜기, run multiple Django server) 본문
python multiprocessing 으로 병렬 작업하기(Django 서버 동시에 여러개 켜기, run multiple Django server)
롯데빙빙바 2020. 10. 19. 01:17개발 배경은 제 글 Django로 채점 서버 만들기에 나와있습니다.
Multiprocessing
python 코드는 보통 동기적으로 작동하며, 코드 한 줄의 실행이 완료되어야 다음 코드를 실행합니다. 그럼 코드의 종료를 기다릴 수 없는 코드를 여러 번 실행해야 할 때는 어떻게 해야할까요? 예를 들어, 아래의 코드를 통해 Django 서버 여러 개를 켜려고 한다고 가정하겠습니다.
import os
for i in range(8000,8010):
os.system(f'python manage.py runserver {i}')
os.system
은 터미널에서 해당 명령어를 실행해주는 메소드입니다.
python manage.py runserver <PORT_NUM>
는 터미널에서 Django 서버를 켜는 명령어입니다.
언뜻 보기엔 8000번 포트부터 8009번 포트까지 10개의 서버가 같이 돌아갈 것 같지만, 실제로는 그렇지 않습니다. 8000번 서버가 켜지고, 터미널에서 해당 서버가 종료될 때까지 다음 서버는 켜지지 않습니다. 이런 상황에서 사용할 수 있는 것이 python의 multiprocessing 패키지입니다.
이 글에서는 제가 적용한 간단한 두 가지의 사용법을 소개하겠습니다. 더욱 자세한 내용은 공식문서를 참고하시길 바랍니다.
Process
from multiprocessing import Process
import os
# 중략
def start_server(student, port):
# target django project 이동 후
os.chdir(BASE_DIR / student)
# 서버 실행
os.system(f'python manage.py runserver {port}')
# students_with_port looks like [('홍길동', 8000), ('김철수', 8001), ...]
if __name__=='__main__':
for student, port in students_with_port:
proc = Process(target=start_server, args=(student,port))
proc.start()
먼저 반복문을 이용한 형태의 multiprocessing입니다. Process
클래스를 통해 프로세스 인스턴스를 만들고, .start()
를 통해 프로세스를 실행할 수 있습니다.
Process
인스턴스를 만들 때, target
키워드 인자에는 실행될 함수를 넣고, 만약 함수 실행 시 전달해야할 인자가 있다면 args
키워드 인자로 전달할 수 있습니다.
여기서 제가 Process
관련 코드에 __name__
관련 조건문을 달아 두었는데, 윈도우에서 이 파일을 직접 실행할 경우, 이 조건문이 없다면 코드가 무한루프에 빠지게 됩니다. 관련 stackoverflow 질문 답변
Pool
from multiprocessing import Pool
import os
# 중략
def start_server(student_with_port):
student, port = student_with_port
# target django project 이동 후
os.chdir(BASE_DIR / student)
# 서버 실행
os.system(f'python manage.py runserver {port}')
# students_with_port looks like [('홍길동', 8000), ('김철수', 8001), ...]
if __name__ == '__main__':
pool = Pool(len(students_with_port))
pool.map(start_server, students_with_port)
다음으로 Pool
을 이용한 multiprocessing입니다. Process
와 크게 다르진 않습니다.
먼저 Pool
인스턴스를 만들 때, 사용할 프로세스 수를 넘깁니다. 저의 경우에는 동시에 켜야할 서버의 수가 학생들의 수 만큼이었으므로, 해당 리스트를 활용하였습니다.
다음으로 .map
을 통해 프로세스를 돌리게 되는데, 첫 번째 인자로 각 프로세스마다 실행할 함수, 두 번째 인자로 함수에 전달할 인자리스트를 넣어줍니다. 두 번째 인자로 전달된 리스트의 요소마다 프로세스가 실행되게 됩니다.
함수에 전달해야 될 인자가 여러 개인 경우, 어떻게 처리해야 할지 몰라서 저는 인자를 튜플로 묶어서 전달하고 함수안에서 풀어서 사용하는 방식을 택했습니다.
이 코드 역시 윈도우에서 실행될 경우, __name__
관련 조건문이 필요합니다.
만약 아래 코드와 같이 함수에 리턴 값이 있다면, 내장 함수 map
과 동일한 동작을 해줍니다. 즉, 해당 프로세스의 결과를 리스트에 담아 리턴하게 됩니다.
def foo(num):
return num*num
numbers = [1, 2, 3, 4]
pool = Pool(4)
squares = pool.map(foo, numbers)
print(squares) # [1, 4, 9, 16]
'개발 간단 팁' 카테고리의 다른 글
프론트 프레임워크를 왜 쓸까? (React, Vue 쓰는 이유) (2) | 2020.11.16 |
---|---|
파이썬으로 파일 수정하기(edit file with python) (0) | 2020.11.08 |
CORB(Cross-Origin Read Blocking)에 대하여 (0) | 2020.11.06 |
Django로 만든 웹 페이지가 iframe에 표시되지 않는 이유(XFrameOptions 허용하기) (1) | 2020.10.11 |
파이썬으로 여러 깃헙 repo 한 번에 받기(python, github) (0) | 2020.10.04 |