먼저 혼동될 수 있는 용어 중 프로그램
과 프로세스
에 대해 간단히 알아보겠습니다.
프로그램과 프로세스는 컴퓨터에서 실행되는 소프트웨어의 두 가지 다른 개념입니다.
프로그램
은 디스크나 메모리에 저장된 명령어의 집합이고, 프로세스
는 프로그램을 실행하는 데 필요한 자원과 상태를 갖는 활성화된 프로그램입니다.
예를 들어, 워드프로세서 프로그램은 디스크에 저장된 파일이지만, 사용자가 이를 실행하면 프로세스가 생성되어 CPU, 메모리, 입출력 장치 등을 사용하여 작업을 수행합니다.
프로그램과 프로세스의 차이점을 이해하는 것은 컴퓨터 시스템의 동작 원리와 성능 향상을 위한 방법을 알아내는 데 도움이 됩니다.
예를 들어, 하나의 프로그램은 여러 개의 프로세스를 생성할 수 있고, 이를 병렬로 실행하여 작업을 빠르게 처리할 수 있습니다. 또한, 여러 개의 프로세스가 동일한 자원을 공유하거나 통신하기 위해서는 운영체제가 제공하는 메커니즘을 사용해야 합니다. 이러한 메커니즘에는 세마포어, 뮤텍스, 파이프, 소켓 등이 있습니다.
프로세스
란 실행 중인 프로그램을 의미합니다. 프로세스는 자신만의 메모리 공간과 자원을 할당받아 독립적으로 작동합니다.
프로세스는 운영체제에 의해 관리되며, 프로세스 간에는 서로의 메모리 공간에 접근할 수 없습니다.
프로세스는 운영체제로부터 메모리 공간을 할당받아 사용합니다. 메모리 공간은 프로세스가 실행되는 동안 필요한 데이터와 명령어를 저장하는 영역입니다.
프로세스의 메모리 공간은 크게 네 가지 구역으로 나눌 수 있습니다.
첫 번째는 코드(code) 영역
입니다.
코드 영역은 프로세스가 실행할 명령어들이 기계어 명령 형태로 저장되는 영역입니다.
코드 영역은 프로세스마다 고유하며, 보통 읽기 전용입니다.
두 번째는 데이터(data) 영역
입니다.
데이터 영역은 프로세스가 정적으로 선언한 전역 변수와 정적 변수가 저장되는 영역입니다.
데이터 영역은 프로그램의 시작과 함께 할당되며, 종료될 때 해제됩니다.
세 번째는 스택(stack) 영역
입니다.
스택 영역은 프로세스가 동적으로 할당하는 지역 변수와 매개 변수, 그리고 함수의 호출과 복귀에 관련된 정보가 저장되는 영역입니다.
스택 영역은 후입선출(LIFO) 방식으로 관리되며, 함수의 호출과 반환에 따라 생성되고 소멸됩니다.
네 번째는 힙(heap) 영역
입니다.
힙 영역은 프로세스가 실행 중에 필요에 따라 동적으로 할당하는 메모리 공간입니다.
힙 영역은 사용자가 직접 관리해야 하며, 필요하지 않은 메모리는 반드시 해제해야 합니다.
힙 영역은 주소 값이 낮은 곳에서 높은 곳으로 증가하는 방향으로 할당됩니다.
쓰레드는 다음에 실행할 명령을 추적하는 자체 프로그램 카운터, 현재 작업 변수를 보유하는 시스템 레지스터, 실행 기록을 포함하는 스택을 포함하는 프로세스 코드를 통한 실행 흐름입니다.
쓰레드는 피어 스레드와 코드 세그먼트, 데이터 세그먼트 및 열린 파일과 같은 몇 가지 정보를 공유합니다. 한 쓰레드가 코드 세그먼트 메모리 항목을 변경하면 다른 모든 쓰레드가 이를 확인합니다.
쓰레드는 경량 프로세스 라고도 합니다. 쓰레드는 병렬성을 통해 애플리케이션 성능을 향상시키는 방법을 제공합니다. 쓰레드는 오버헤드를 줄임으로써 운영 체제의 성능을 향상시키는 소프트웨어 접근 방식을 나타냅니다. 스레드는 기존 프로세스와 동일합니다.
각 쓰레드는 정확히 하나의 프로세스에 속하며 프로세스 외부에는 쓰레드가 존재할 수 없습니다. 각 쓰레드는 별도의 제어 흐름을 나타냅니다. 쓰레드는 공유 메모리 다중 프로세서(shared memory multiprocessors)에서 응용 프로그램의 병렬 실행을 위한 적합한 기반을 제공합니다.
쓰레드는 메모리 공간을 효율적으로 관리하기 위해, 두 가지 주요한 메모리 영역을 사용합니다.
첫 번째는 스택(stack)
이라고 부르는 영역으로, 정적인 데이터와 함수의 매개변수, 지역 변수 등이 저장됩니다.
스택은 후입선출(LIFO) 방식으로 작동하며, 함수가 호출되거나 종료될 때마다 스택의 상단에 데이터가 쌓이거나 제거됩니다.
스택은 컴파일 시점에 크기가 결정되며, 빠른 접근 속도를 제공합니다.
두 번째는 힙(heap)
이라고 부르는 영역으로, 동적인 데이터와 객체, 배열 등이 저장됩니다.
힙은 스택과 달리 실행 시점에 크기가 결정되며, 필요에 따라 메모리를 할당하거나 해제할 수 있습니다.
힙은 스택보다 접근 속도가 느리지만, 더 많은 메모리 공간을 제공합니다.
힙에 저장된 데이터는 가비지 컬렉션(garbage collection)이라는 기능을 통해 자동으로 관리됩니다.
쓰레드는 프로세스보다 생성과 소멸이 빠르고 비용이 적게 듭니다.
쓰레드는 같은 프로세스 내에서 메모리 공간과 자원을 공유하므로 통신이 용이합니다.
쓰레드는 Context Switching 시간을 최소화합니다.
쓰레드는 멀티 프로세서 환경에서 병렬 처리가 가능하여 성능을 향상시킬 수 있습니다.
쓰레드는 메모리 공간과 자원을 공유하므로 동기화 문제가 발생할 수 있습니다.
예를 들어, 한 쓰레드가 공유 데이터를 수정하면 다른 쓰레드에 영향을 줄 수 있습니다.
쓰레드는 운영체제에 따라 구현 방식이 다를 수 있으므로 이식성이 떨어질 수 있습니다.
예를 들어, 윈도우와 리눅스에서 쓰레드를 다르게 처리합니다.
쓰레드는 너무 많이 생성하면 오버헤드가 발생하여 성능이 저하될 수 있습니다.
쓰레드는 크게 2 종류가 있습니다.
사용자가 관리하는 쓰레드입니다.
이 경우 스레드 관리 커널은 스레드의 존재를 인식하지 못합니다. 스레드 라이브러리에는 스레드 생성 및 삭제, 스레드 간 메시지 및 데이터 전달, 스레드 실행 예약, 스레드 컨텍스트 저장 및 복원을 위한 코드가 포함되어 있습니다.
애플리케이션은 단일 스레드로 시작됩니다.
운영체제의 코어인 커널에서 작동하는 운영체제 관리 쓰레드입니다.
이 경우 스레드 관리는 커널에 의해 수행됩니다.
응용프로그램 영역에는 스레드 관리 코드가 없습니다.
커널 스레드는 운영 체제에서 직접 지원합니다.
모든 응용 프로그램은 다중 스레드로 프로그래밍될 수 있습니다. 애플리케이션 내의 모든 스레드는 단일 프로세스 내에서 지원됩니다.
커널은 프로세스 전체와 프로세스 내의 개별 스레드에 대한 컨텍스트 정보를 유지 관리합니다.
커널에 의한 스케줄링은 스레드 기반으로 수행됩니다.
커널은 커널 공간에서 스레드 생성, 예약 및 관리를 수행합니다.
멀티 쓰레딩이란 하나의 프로세스 내에서 여러 개의 쓰레드를 생성하고 실행하는 기법입니다.
쓰레드는 프로세스의 자원을 공유하면서 동시에 작업을 수행할 수 있습니다.
CPU의 활용도를 높일 수 있습니다. 한 쓰레드가 입출력 작업을 기다리는 동안 다른 쓰레드가 계산 작업을 수행할 수 있습니다.
메모리의 효율성을 높일 수 있습니다. 쓰레드는 프로세스의 메모리 공간을 공유하기 때문에 쓰레드 간의 데이터 전달이 용이하고, 메모리 낭비가 줄어듭니다.
응답성을 향상시킬 수 있습니다. 여러 쓰레드가 동시에 작업을 수행하면 사용자의 요청에 빠르게 반응할 수 있습니다.
동기화 문제가 발생할 수 있습니다. 여러 쓰레드가 공유 자원에 접근하면서 데이터의 일관성을 유지하기 위해 동기화 기법이 필요합니다. 동기화 기법은 성능 저하와 복잡도 증가를 야기할 수 있습니다.
교착 상태가 발생할 수 있습니다. 두 개 이상의 쓰레드가 서로가 가진 자원을 기다리면서 작업을 진행하지 못하는 상황입니다. 교착 상태를 해결하기 위해서는 교착 상태를 예방하거나 탐지하고 복구하는 알고리즘이 필요합니다.
오버헤드가 발생할 수 있습니다. 쓰레드의 생성, 스케줄링, 전환 등에 드는 비용입니다. 쓰레드의 개수가 너무 많으면 오버헤드가 커져서 성능이 저하될 수 있습니다.
프로세스와 쓰레드의 차이를 요약하면 다음과 같습니다.
프로세스는 독립적인 메모리 공간과 자원을 가지고, 쓰레드는 공유하는 메모리 공간과 자원을 가집니다.
프로세스는 운영체제에 의해 관리되고, 쓰레드는 운영체제 또는 프로그래머에 의해 관리됩니다.
프로세스는 하나가 block되면 block이 해제될 때 까지 다른 프로세스는 실행할 수 없고, 쓰레드는 하나가 blcok되더라도 동일한 작업의 두 번째 쓰레드가 실행될 수 있습니다.
프로세스 간에는 메모리 공간에 접근할 수 없고, 쓰레드 간에는 메모리 공간에 접근할 수 있습니다.