하나에 프로세스에는 여러 스레드가 있을 수 있다. 컴퓨터는 실행 과정에서 여러 프로세스가 동시에 실행될 수 있고, 그 프로세스를 이루는 스레드는 여러 개 있을 수 있다. 이때, 여러 프로세스를 동시에 실행하는 것을 멀티프로세스, 그리고 여러 스레드로 프로세스를 동시에 실행하는 것을 멀티스레드라고 한다.
여기서 한 가지 궁금증이 생긴다.
'동일한 작업을 수행하는 단일 스레드 프로세스 여러 개를 실행하는 것과 하나의 프로세스를 여러 스레드로 실행하는 것은 무엇이 다를까?'
예를 들어 "hello"를 화면에 출력하는 간단한 프로그램이 있다고 하자. 이 프로그램을 세 번 fork하여 실행하면 화면에는 "hello"가 세 번 출력된다. 이 프로그램 내에 "hello"를 출력하는 스레드를 세 개 만들어 실행해도 화면에는 "hello"가 세 번 출력된다. 이 둘은 무엇이 다를까?
"hello"가 세 번 출력되는 결과는 같은데 말이다.
여기에는 큰 차이가 있다. 프로세스는 기본적으로 자원을 공유하지 않지만, 스레드끼리는 같은 프로세스 내의 자원을 공유한다.
프로세스와 스레드의 자원 관리
프로세스는 독립적인 메모리 공간을 가지므로, 서로 간섭 없이 실행된다. 반면 스레드는 같은 프로세스 내에서 실행되기 때문에, 데이터의 공유가 가능하지만 이로 인해 경쟁 상태(race condition)와 같은 문제가 발생할 수 있다.
프로세스를 fork하여 같은 작업을 하는 동일한 프로세스 두 개를 동시에 실행하면 코드 영역, 데이터 영역, 힙 영역 등을 비롯한 모든 자원이 복제되어 메모리에 적재된다. 한 마디로 PID, 저장된 메모리 주소를 제외하면 모든 것일 동일한 프로세스 두 개가 통째로 메모리에 적재되는 것이다.
이에 반해 스레드들은 각기 다른 스레드 ID, 프로그램 카운터 값을 포함한 레지스터 값, 스택을 가질뿐 프로세스가 가지고 있는 자원을 공유한다. 즉, 같은 프로세스 내의 모든 스레드는 동일한 주소 공간의 코드, 데이터, 힙 영역을 공유하고, 열린 파일과 같은 프로세스 자원을 공유한다.
스레드는 프로세스의 자원을 공유하기 때문에 서로 협력과 통신에 유리하다
성능
멀티스레드가 멀티프로세스 방식보다 더 효율적일 수 있는 이유는 스레드 간의 자원 공유 덕분에 메모리 사용과 컨텍스트 스위칭(context switching)에서 상대적으로 경량화된 작업을 수행할 수 있기 때문이다.
오류 전파
그러나 스레드는 자원을 공유하기 때문에 한 스레드의 오류가 전체 프로세스에 영향을 미칠 수 있다. 반면, 프로세스는 서로 독립적이므로 한 프로세스의 오류가 다른 프로세스에 영향을 미치지 않는다.
결론
프로세스를 여러 개 실행하는 것과 하나의 프로세스 내에서 여러 스레드를 실행하는 것은 자원 관리, 성능, 오류 전파 측면에서 큰 차이가 있다.
멀티 스레드는 프로세스를 생성하여 자원을 할당하는 시스템 콜이 감소함으로써 자원의 효율적 관리가 가능하다.
프로세스 간의 통신(IPC)보다 스레드 간의 통신 비용이 적어 작업들 간 부담이 감소한다.
대신, 멀티 스레드를 사용할 때는 공유 자원으로 인한 문제 해결을 위해 '동기화'에 신경써야 한다.
리소스 효율성
멀티스레드는 프로세스보다 적은 메모리 오버헤드를 가지므로, 자원을 보다 효율적으로 사용할 수 있다. 프로세스는 각각 독립적인 메모리 공간을 가지지만, 스레드는 같은 프로세스 내에서 메모리를 공유하므로 메모리 사용량이 줄어든다.
통신 비용 절감
스레드 간의 통신은 같은 메모리 공간을 사용하므로, IPC(Inter-Process Communication)보다 훨씬 빠르다.
응답성 향상
멀티스레드 프로그램은 사용자 인터페이스와 같은 작업을 별도의 스레드에서 처리할 수 있어, 메인 스레드가 사용자 입력에서 즉시 반응할 수 있다. 따라서 프로그램의 응답성이 향상된다.
작업 분할
멀티스레드는 복잡한 작업을 여러 개의 하위 작업으로 나누어 동시에 처리하는 데 유리하다. 이는 CPU 코어를 최대한 활용할 수 있게 해준다.
유연성
스레드는 프로세스보다 더 쉽게 생성하고 종료할 수 있으므로, 동적인 작업 부하에 보다 유연하게 대응할 수 있다.
물론 멀티스레드를 사용할 때는 동기화와 같은 문제를 신경 써야 한다. 공유 자원에 대한 접근을 안전하게 관리하지 않으면 데이터 손상이 발생할 수 있기 때문에, 적절한 동기화 기법(뮤텍스, 세마포어 ...)을 사용하여 문제를 해결해야 한다. 이러한 점이 멀티스레드의 단점이지만 장점이 더 많기 때문에 멀티스레드가 선호된다.