파이썬으로 멀티프로세싱 코드를 열심히 작성했는데, 내 PC(리눅스)에서는 잘만 돌아가던 코드가 동료의 윈도우 PC에서는 뜬금없는 오류를 뿜어내는 당황스러운 경험, 다들 한 번쯤 있으신가요? 분명 코드 한 줄 건드리지 않았는데 말이죠. 저도 최근에 이런 문제로 반나절을 헤맨 적이 있는데요, 원인은 바로 눈에 보이지 않는 운영체제(OS)의 차이에 있었습니다. 😊
윈도우의 숨겨진 제약: WaitForMultipleObjects() 🤨
문제의 핵심은 윈도우의 WaitForMultipleObjects라는 API에 있습니다. 이 함수는 여러 개의 이벤트나 프로세스 핸들이 완료되기를 기다리는 역할을 하는데요. 이름 그대로 여러 객체를 '기다리는' 아주 중요한 친구입니다. 파이썬의 multiprocessing 모듈도 내부적으로 이 API를 사용하여 여러 워커 프로세스들이 작업을 마칠 때까지 기다리죠.
하지만 이 친구에겐 치명적인(?) 제한이 하나 있습니다. 바로 한 번에 기다릴 수 있는 핸들의 수가 64개(정확히는 MAXIMUM_WAIT_OBJECTS 매크로 값)로 제한된다는 점입니다. 즉, 64개보다 많은 프로세스를 만들어 동시에 제어하려고 하면 "나 64명까지만 받을 수 있어!"라며 오류를 뱉어내는 거죠. 우리가 Pool(processes=100) 같은 코드를 짰을 때 윈도우에서 문제가 생기는 이유가 바로 이것 때문입니다.
이 64개 제한은 파이썬만의 문제가 아니라, 윈도우 API 자체의 제약입니다. 따라서 C++, C# 등 다른 언어로 윈도우 프로그램을 개발할 때도 동일하게 마주칠 수 있는 문제입니다.
자유로운 리눅스: select, poll, epoll의 세계 🐧
반면에 리눅스는 어떨까요? 리눅스는 프로세스 간 통신(IPC)이나 동기화에 WaitForMultipleObjects와는 다른 방식을 사용합니다. 바로 select, poll, epoll 같은 I/O 멀티플렉싱 기술이죠.
이 기술들은 여러 파일 디스크립터(File Descriptor, 리눅스에서는 프로세스, 소켓 등 모든 것을 파일처럼 다룹니다)의 상태 변화를 한 번에 감지하고 처리하는 방식입니다. 덕분에 윈도우와 같은 '64개'라는 인위적인 제한에서 훨씬 자유롭습니다.
| 항목 | 핸들 수 제한 | 특징 |
|---|---|---|
| select() | 기본 1024개 | 가장 오래되고 호환성이 좋지만, 성능 저하 이슈가 있음 |
| poll() | 시스템 메모리에 따름 | select()의 단점을 개선, 더 많은 핸들 처리 가능 |
| epoll() | 시스템 메모리에 따름 | 매우 효율적인 최신 방식으로, 수만 개 이상의 핸들도 거뜬함 |
특히 최신 리눅스 커널에서 주로 사용하는 epoll은 사실상 시스템의 메모리가 허용하는 한까지 핸들을 다룰 수 있어, 수십, 수백 개의 프로세스를 관리하는 데 전혀 문제가 없습니다.
리눅스 vs 윈도우: 코드로 비교하기 🧪
간단한 파이썬 코드로 두 운영체제의 차이를 직접 확인해볼까요?
📝 워커 100개 생성 테스트 코드
from multiprocessing import Pool
import time
def work(x):
# 각 워커가 0.1초 동안 어떤 작업을 수행한다고 가정
time.sleep(0.1)
return x * x
# 워커 프로세스를 100개 생성
if __name__ == '__main__':
# 윈도우에서는 이 숫자가 64 이상이면 문제가 될 수 있습니다.
num_processes = 100
with Pool(processes=num_processes) as pool:
results = pool.map(work, range(1000))
print(f"{num_processes}개의 워커로 작업 완료!")
print(f"결과 (앞 10개): {results[:10]}")
위 코드를 리눅스 환경에서 실행하면 아무런 문제 없이 100개의 워커 프로세스가 생성되고 작업이 완료됩니다. 하지만 윈도우에서는 Pool 객체가 내부적으로 64개 이상의 프로세스 핸들을 기다려야 하는 상황이 오면 ValueError가 발생할 수 있습니다.
리눅스라고 해서 워커 수를 무한정 늘릴 수 있는 것은 아닙니다. OS 레벨의 '제한'은 없지만, 시스템의 물리적인 자원(CPU 코어 수, 메모리 용량)에 따라 성능이 좌우됩니다. 너무 많은 프로세스는 오히려 잦은 컨텍스트 스위칭으로 성능을 저하시키거나, 메모리 부족(Out of Memory)으로 시스템 전체를 마비시킬 수 있습니다.
윈도우 vs 리눅스 멀티프로세싱 핵심 요약
자주 묻는 질문 ❓
결론적으로, 리눅스는 멀티프로세싱 워커 수에 대한 OS 제한이 거의 없는 반면, 윈도우는 64개라는 명확한 제한이 존재합니다. 따라서 여러 플랫폼에서 동작해야 하는 프로그램을 개발한다면, 이러한 보이지 않는 '벽'을 항상 염두에 두고 가장 보수적인 환경(윈도우)을 기준으로 설계하는 것이 안전합니다. 😊
'Coding' 카테고리의 다른 글
| AI가 코딩 메이트? 개발 효율을 200% 올리는 Kiro 사용법 (1) | 2025.07.17 |
|---|---|
| Node.js와 Git 설정으로 끝내는 윈도우 Claude Code 네이티브 설치법 (1) | 2025.07.15 |
| 스타트업과 개발자를 위한 네이버/카카오 지도 API 요금제 비교 분석 (0) | 2025.07.05 |
| 내 서비스에 지도를 입히자! 네이버 지도 API 사용 가이드 (4) | 2025.07.05 |
| 내 서비스에 지도를 입히자! 카카오 지도 API 사용 가이드 (2) | 2025.07.05 |