멀티 프로세스 vs 멀티 스레드
멀티 프로세스와 멀티 스레드는 한 애플리케이션에 대한 처리방식이다. 단순히 프로그램을 여러개 띄워놓는 것이 아니라, 언제 어느 때에 어느 방식으로 애플리케이션을 처리하느냐에 따라 다른 것으로 이해해야 한다.
단일이 아닌 여러 개의 프로세스, 스레드가 다중으로 돌아감으로써 성능 향상 등 여러가지 효과를 얻을 수 있다. 하지만 이로 인한 여러 부가적인 문제점도 발생하게 된다.
멀티 프로세스
운영체제에서 하나의 응용 프로그램에 대해서 동시에 여러 개의 프로세스를 실행할 수 있게 하는 기술이다. 하나의 프로그램 실행에 대해 하나의 프로세스가 메모리에 생성되지만, 부가적인 기능을 위해 여러 개의 프로세스를 생성하는 것이다.
멀티 프로세스 내부를 보면, 하나의 부모 프로세스가 여러 개의 자식 프로세스를 생성한다. 이를 통해 다중 프로세스를 구성하는 구조이다. 한 프로세스가 실행되는 도중 프로세스를 생성하는 시스템 콜을 통해 새로운 프로세스들을 생성할 수 있다.
다른 프로세스를 생성하는 프로세스를 부모 프로세스(Parent Process)라 하고, 다른 프로세스에 의해 생성된 프로세스를 자식 프로세스(Child Process)라 한다.
부모 프로세스와 자식 프로세스는 각각 고유한 PID(Process ID)를 가지고 있다. 부모 프로세스는 자식 프로세스의 PID를 알고 있고, 이를 통해 자식 프로세스를 제어할 수 있다. 자식 프로세스는 부모 프로세스의 PID를 알고 있어서 부모 프로세스와의 통신을 할 수 있다.
부모 프로세스와 자식 프로세스는 엄연히 서로 다른 프로세스로 독립적으로 실행된다. 그리고 독립적인 메모리 공간을 할당받기 때문에, 서로 다른 작업을 수행한다.
예) 웹 브라우저의 탭, 새로운 창 → 같은 브라우저 프로그램의 실행이지만, 서로 다른 사이트를 실행한다.
멀티 프로세스의 장점
1. 프로그램 안정성
멀티 프로세스에서는 각 프로세스가 독립적인 메모리 공간을 가진다. 따라서 하나의 프로세스가 비정상적으로 종료되어도 다른 프로세스에 영향을 주지 않는다. 이를 통해 프로그램 전체의 안정성을 확보한다.
예를 들어 크롬 브라우저에서 한 탭의 웹사이트의 작동이 중단되었다고 해도, 다른 탭은 문제 없이 이용할 수 있다. 이는 곧 자식 프로세스가 여러 개 생성되어 별도의 메모리에서 실행되고 있기 때문에 가능하다.
2. 프로그램 병렬성
멀티 프로세스와 여러 개의 CPU 코어를 활용해서 다중 CPU 시스템에서 각 프로세스를 병렬적으로 실행해서 성능을 향상할 수 있다.
멀티 프로세스 환경에서 각 프로세스는 독립적이므로, 새로운 기능이나 모듈을 추가할 때 다른 프로세스에 영향을 주지 않는다. 그래서 시스템의 규모를 쉽게 확장할 수 있다.
멀티 프로세스를 사용해서 여러 대의 서버에 요청을 분산시켜 처리하게 되면, 시스템의 규모를 쉽게 확장할 수 있고, 서버의 장애나 다운타임을 최소화할 수 있게 된다.
멀티 프로세스의 단점
1. Process Context Switching Overhead
컨텍스트 스위칭 과정에서 성능저하가 발생할 수 있다. 프로세스를 컨텍스트 스위칭하게 되면, CPU는 다음 프로세스의 정보를 불러오기 위해서 메모리를 검색해야 하고, CPU 캐시 메모리를 초기화하고, PCB에 현재 프로세스의 상태를 저장하고, 불러올 데이터를 준비해야 한다.
빈번한 Context Switching 작업은 비용 오버헤드를 발생시킨다. 따라서 멀티 프로세스 환경에서는 Context Switching Overhead를 최소화하는 방법이 중요하다.
이를 위해서 프로세스 수를 적정하게 유지하거나, I/O bound 작업이 많거나, CPU bound 작업이 많은 프로세스를 분리해서 관리하는 등의 방법을 고려해야 한다.
2. 자원 공유 비효율성
멀티 프로세스는 각 프로세스가 독립적인 메모리 공간을 가진다. 즉 프로세스가 증가할수록 메모리 사용량이 증가하게 된다.
만약 각 프로세스간에 자원 공유가 필요할 경우 IPC를 통해 프로세스간의 통신이 이루어져야 한다.
cf) IPC
IPC란 운영체제 상에서 실행 중인 프로세스 간에 정보를 주고 받는 메커니즘이다. 이때 파이프, 소켓, 메세지 큐 등 방법이 활용된다. 이때 데이터를 복사하거나 전송하는 과정에서 오버헤드가 발생한다.
멀티 스레드
스레드는 하나의 프로세스 내에 있는 실행 흐름 단위이다. 즉 멀티 스레드는 하나의 프로세스 안에 여러 개의 스레드가 있는 것을 의미한다. 따라서 하나의 프로그램에서 두 가지 이상의 동작을 동시에 처리하는 것이 가능해진다.
대표적인 멀티스레드 응용 프로그램은 웹서버가 있다. 사용자가 서버의 Database에 데이터를 요청하는 동안 브라우저의 다른 기능을 이용할 수 있다. 하나의 스레드가 데이터를 조회하는 동안 지연되더라도, 다른 스레드는 작업을 지속할 수 있다.
멀티 프로세스는 웹 브라우저의 탭, 창이라면, 멀티 스레드는 브라우저의 단일 탭, 창에서 이벤트 루프나, 네트워크 처리 등을 관리하는데 사용된다고 이해할 수 있다.
멀티 스레드의 장점
많은 운영체제들이 멀티 프로세스를 지원함에도 멀티 스레딩을 기본으로 한다. 그 이유는 아래와 같다.
1. 스레드가 프로세스보다 더 가볍다.
스레드는 프로세스 내에서 생성되기 때문에 프로세스보다 용량이 가볍다. 스레드는 프로세스와 달리 코드, 데이터, 스택 영역을 제외한 나머지 자원을 서로 공유하기 때문에 내장된 데이터 용량이 프로세스보다 적다. 스레드를 생성하고 제거할 때, 프로세스 내부의 자원만 관리하면 되므로, 프로세스를 생성하고 제거하는 것보다 훨씬 빠르다.
2. 자원의 효율성
멀티 스레드는 하나의 프로세스 내에서 여러 개의 스레드가 생성되는 것이기 때문에, heap 영역과 같은 공유 메모리에 대해서 스레드 간의 자원 공유가 가능하다. 이를 통해 프로세스간 통신을 하지 않고도 데이터를 공유할 수 있기 때문에, 효율적인 자원 활용이 가능하다.
3. Context Switching 비용 감소
멀티 스레드에도 컨텍스트 스위칭에 대한 오버해드가 발생한다. 그렇지만 상대적으로 프로세스 컨텍스트 스위칭 오버헤드보다 비용이 낮다.
스레드 컨텍스트 스위칭을 진행할 때는 스레드 간의 공유 자원을 제외한 스레드 정보만 교체하면 되므로, 프로세스 컨텍스트 스위칭 비용보다 상대적으로 낮다.
4. 응답 시간 단축
스레드 간의 통신이나, 자원 공유가 호율적이고 프로세스보다 가볍다는 장점으로 인해 멀티 프로세스보다 빠른 응답시간을 가진다.
웹 서버에서 클라이언트 요청을 처리할 때, 멀티 프로세스 방식에서는 각 요청마다 프로세스를 생성해서 처리하는 것은 오버헤드가 크다. 하지만 멀티 스레드 방식은 하나의 프로세스 내에서 여러 개의 스레드로 요청을 처리할 수 있다. 따라서 오버헤드가 감소하므로 더욱 빠른 응답 시간을 보장한다.
멀티 스레드 단점
1. 안정성 문제
멀티 프로세스에서는 각 프로세스가 독립적으로 동작한다. 따라서 하나의 프로세스에서 문제가 발생해도 다른 프로세스들은 영향을 받지 않는다. 따라서 프로그램이 죽지 않고 계속 동작할 수 있다.
멀티 스레드 환경에서는 기본적으로 하나의 스레드에서 문제가 발생하면 다른 스레드들도 영향을 받아 전체 프로그램이 종료될 수 있다.
2. 동기화로 인한 성능저하
여러 개의 스레드가 공유 자원에 동시에 접근할 수 있으므로, 동기화 문제가 발생할 수 있다. 예를 들어 여러 스레드가 동시에 하나의 자원을 변경한다면, 의도되지 않은 값을 읽어 서비스에 영향을 미치게 된다. 따라서 스레드 간의 동기화는 데이터 접근을 제어하기 위한 필수적 기능이다.
여러 스레드들이 자원에 접근하는 것을 순차적으로 통제하는 것이 동기화 작업이다. 그러면 동시 접근으로 인한 동시 수정과 같은 현상을 일어나지 않는다. 하지만 여러 스레드 접근을 제한하기 때문에 병목 현상이 일어나 성능 저하 가능성이 높다는 단점이 있다.
이를 해결하기 위해 임계영역에 대해서 뮤텍스, 세마포어 방식을 활용한다.
cf) 임계영역
멀티 스레드 환경에서 임계 영역은 공유 자원을 접근하는 코드 영역을 의미한다. 대표적으로 전역 변수나, heap 메모리 영역이다.
cf) 뮤텍스(Mutex)
임계영역에 진입하기 전에 lock을 획득하고, 임계 영역을 빠져나올 때 lock을 해제하여 다른 스레드들이 접근할 수 있도록 한다. 즉 오직 1개의 스레드만에 공유 자원에 접근할 수 있도록 제어하는 기법이다.
cf) 세마포어(Semaphore)
동시에 접근 가능한 스레드의 개수를 지정할 수 있다. 세마포어 값이 1이면 뮤텍스와 동일하지만, 값이 2 이상이면 동시에 접근 가능한 스레드의 수를 제어할 수 있다. 스레드가 임계 영역에 진입하기 전에 세마포어 값을 확인하고, 허용된 범위 내에 있을 때만 lock을 획득할 수 있는 형식이다.
3. 데드락
다수의 프로세스나 스레드가 서로 자원을 점유하고, 다른 프로세스나 스레드가 점유한 자원을 기다리는 상황에서 발생하는 교착상태를 의미한다.
여러 개의 스레드가 서로 대기하면서 무한정 기다리는 무한 루프와 같은 상태이다.
이러한 현상은 스레드의 특징인 공유 자원에 대한 동시 접근으로 발생하는 문제이기 때문에, 이를 방지하기 위한 상호배제, 점유 대기 등의 알고리즘을 통해 해결해야 한다.
멀티 프로세스에서도 IPC를 통해 공유 자원을 활용할 수 있기 때문에 데드락 상태에 빠질 수 있다.
4. Context Switching Overhead
멀티 프로세스보다 컨텍스트 스위칭으로 인한 오버헤드가 작지만, 비용 자체는 발생한다. 특히 스레드가 많을수록 그만큼 컨텍스트 스위칭이 발생하고, 성능저하로 이어진다.
일반적으로 스레드가 많으면 많을수록 동시처리 수가 늘어나기 때문에 무조건 좋다고 생각할 수 잇지만, 꼭 그렇지 않을 수도 있다는 것이다.
5. 디버깅이 어려움
여러 개의 스레드가 동시에 실행되기 때문에, 각 스레드의 동작을 추적하기 어렵다. 코드를 디버깅하는 도중 다른 스레드가 실행될 수 있고, 어떤 스레드가 어떤 자원에 접근하고 어떤 순서로 실행되는지 파악하기 어려울 수 있다.
이를 위해 스레드 간의 상호작용과 동기화 기법을 잘 이해하고 디버깅 도구를 활용해야 한다.