안녕하세요. dev_writer입니다.
이번에는 스터디의 2주 차 내용인, 프로세스와 스레드에 대해 정리해 보겠습니다.
프로세스
먼저, 프로세스의 정의를 보겠습니다.
프로세스(process)는 컴퓨터에서 연속적으로 실행되고 있는 프로그램이다. 종종 스케줄링의 대상이 되는 작업(task)이라는 용어와 거의 같은 의미로 쓰인다.
...
프로그램은 일반적으로 하드 디스크 등에 저장되어 있는 실행코드를 뜻하고, 프로세스는 프로그램을 구동하여 프로그램 자체와 프로그램의 상태가 메모리 상에서 실행되는 작업 단위를 지칭한다. 예를 들어, 하나의 프로그램을 여러 번 구동하면 여러 개의 프로세스가 메모리 상에서 실행된다. - 위키백과
위키백과에 따르면, 프로그램과 프로세스의 구분은 실행 여부로 나눌 수 있음을 볼 수 있습니다.
즉,
- 프로그램은 하드 디스크 등에 저장되어 있는 실행코드이다.
- 프로그램이 실행되면 프로세스가 되며, 이것은 메모리 상에서 실행된다.
라고 할 수 있습니다.
프로세스의 종류
프로세스는 크게 포그라운드 프로세스와 백그라운드 프로세스로 나눌 수 있습니다.
포그라운드 프로세스 (foreground process)
포그라운드 프로세스는 사용자가 볼 수 있는 공간에서 실행되는 프로세스를 뜻합니다. 메모장, 게임 등이 해당됩니다.
백그라운드 프로세스 (background process)
백그라운드 프로세스는 사용자가 볼 수 없는 공간에서 실행되는 프로세스를 뜻합니다.
이때, 사용자와 상호작용하지 않고 정해진 일을 수행하는 백그라운드 프로세스를 데몬 (daemon) 프로세스라 합니다. (유닉스 기준, 윈도우는 서비스)
프로세스 제어 블록 (PCB)
프로세스 제어 블록은 프로세스에 대한 정보를 저장해 둔 자료구조입니다.
PCB는 메모리의 구성 영역 (커널 영역, 사용자 영역) 중 커널 영역에 저장됩니다.
그리고 PCB에는 프로세스 ID (PID), 프로세스 상태, CPU 스케줄링 정보 등 다양한 정보가 들어가 있습니다.
프로세스 제어 블록이 필요한 이유는?
모든 프로세스는 실행을 위해 CPU 자원을 필요로 합니다.
그러나 이전 글에서 다뤘듯이, CPU 자원은 한정적입니다. 그렇기에 많은 프로세스들이 CPU 자원을 필요로 하는 상황을 제어해야 하는데, 이를 위해 프로세스 제어 블록이 필요하게 되었습니다.
운영체제는 수많은 프로세스들 사이에서 PCB로 특정 프로세스를 식별하고 해당 프로세스를 처리하는 데 필요한 정보를 판단합니다.
문맥 교환 (Context Switch)
문맥 교환이 무엇인지 알기 위해서는, 먼저 문맥이 무엇인지 알아봐야 합니다.
문맥 (context)이란, 하나의 프로세스 수행을 재개하기 위해 기억해야 할 정보를 뜻합니다.
위에서 프로세스는 실행을 위해 CPU 자원을 필요로 한다고 하였는데요, 만약 특정 프로세스 (메모 프로세스라고 가정)가 실행 중이라면, 이와 관련된 정보 (어디까지 메모를 썼는지, 마지막 작성 시각은 언제인지 등등)가 있을 것입니다.
이때 다른 프로세스가 실행되어야 한다면, 기존 프로세스는 자신이 사용하던 CPU의 자원 (레지스터, 프로그램 카운터 등)에 대한 정보를 기록해 놔야 후에 복귀해도 문제없이 이어서 진행할 수 있을 것입니다.
정리하자면, 문맥 교환은 프로세스가 교체될 때 운영체제가 프로세스의 PCB에 문맥을 백업하고 뒤이어 실행할 프로세스의 문맥을 복구하는 과정을 뜻합니다.
문맥 교환은 매우 빠르게 번갈아 가며 수행되기에 우리의 눈에는 프로세스들이 동시에 실행되는 것처럼 보이나, 너무 자주 하면 오버헤드가 발생할 수 있어 좋은 것은 아닙니다.
프로세스의 메모리 영역
프로세스가 생성되면 커널 영역에 PCB가 만들어지는데, 사용자 영역은 어떻게 관리될까요?
프로세스는 사용자 영역에서 코드 영역, 데이터 영역, 힙 영역, 스택 영역으로 나뉘어 저장됩니다.
코드 영역
- 코드 영역은 실행할 수 있는 코드 (기계어로 이루어진 명령어)가 저장됩니다.
- 읽기 전용 공간입니다. CPU가 실행할 명령어가 담겨있기 때문입니다.
데이터 영역
- 프로그램이 실행되는 동안 유지할 데이터가 저장되는 공간입니다.
- 전역 변수 등이 저장되며, 코드 영역과 데이터 영역은 크기가 변하지 않습니다.
힙 영역
- 프로그래머가 직접 할당할 수 있는 저장 공간입니다.
- 메모리 공간을 반환하지 않을 경우, 메모리 내에 계속 남아 메모리 누수 문제가 발생할 수 있습니다.
스택 영역
- 데이터를 일시적으로 저장하는 공간입니다.
- 함수의 매개 변수, 지역 변수가 대표적입니다.
프로세스 상태와 계층 구조
다음으로는 프로세스의 상태와 계층 구조에 대해 알아보겠습니다.
프로세스 상태
프로세스 상태는 <생성>, <준비>, <실행>, <대기>, <종료> 5가지 상태로 구분됩니다.
- 생성 상태
- 이제 막 메모리에 적재되어 PCB를 할당받은 상태입니다.
- 준비가 완료되었다면 준비 상태로 변합니다.
- 준비 상태
- 당장이라도 CPU를 할당받아 실행할 수 있지만, 자신의 차례가 아니기 때문에 기다리는 상태입니다.
- 자신의 차례가 된다면 실행 상태로 됩니다. (= 이 과정을 디스패치라 합니다.)
- 실행 상태
- CPU를 받아 실행 중인 상태입니다.
- 할당된 시간을 모두 사용했다면 (타이머 인터럽트 발생) 준비 상태로 됩니다.
- 실행 도중 입출력장치를 사용하면 입출력 작업이 끝날 때까지 대기 상태로 됩니다.
- 대기 상태
- 프로세스가 실행 도중 입출력장치를 사용하는 경우입니다. (= 대부분의 원인입니다.)
- 입출력 작업은 CPU에 비해 느리기에, 이 경우 대기 상태로 접어듭니다.
- 입출력 작업이 끝나면 (입출력 완료 인터럽트를 받으면) 준비 상태로 됩니다.
- 종료 상태
- 프로세스가 종료된 상태입니다.
- PCB, 프로세스의 메모리 영역을 정리합니다.
프로세스 계층 구조
프로세스는 실행 도중 시스템 콜을 통해 다른 프로세스를 생성할 수 있습니다. 이때 시스템 콜을 호출한 프로세스를 부모 프로세스, 생성된 프로세스를 자식 프로세스라 합니다. 서로 다른 프로세스라 서로 다른 PID를 가집니다. 일부 운영체제에서는 자식 프로세스의 PCB에 부모 프로세스의 PID (PPID)가 기록되기도 합니다.
자식 프로세스 또한 또 다른 자식 프로세스를 만들 수 있으며, 그렇기에 프로세스는 계층 구조로 관리될 수 있습니다.
프로세스 생성 기법
많은 운영체제 (윈도우 제외)에서는 복제와 옷 갈아입기 과정을 통해 프로세스를 만들어냅니다.
- 부모 프로세스는 fork 시스템 콜을 통해 자신의 복사본을 자식 프로세스로 생성합니다. (복제)
- 자식 프로세스는 exec 시스템 콜을 통해 자신의 메모리 공간을 다른 프로그램으로 교체합니다. (옷 갈아입기)
- 자신의 메모리 공간을 새로운 프로그램으로 덮어쓰게 합니다.
- 코드/데이터 영역은 실행할 프로그램으로 바뀌고, 나머지 영역은 초기화됩니다.
- 자식 프로세스가 exec 시스템 콜을 호출하지 않을 경우, 부모 프로세스와 자식 프로세스는 같은 코드를 병행하여 실행하는 프로세스가 됩니다.
스레드
스레드는 프로세스를 구성하는 실행 흐름의 단위를 뜻합니다. 실행 흐름의 단위인 만큼, 하나의 프로세스는 여러 개의 스레드를 가질 수 있습니다.
스레드의 구성 요소
스레드는 스레드 ID, 프로그램 카운터를 비롯한 레지스터 값과 스택 등을 가지고 있으며, 실행에 필요한 최소한의 정보를 가지고 있습니다.
프로세스를 이루는 스레드들은 프로세스의 자원을 공유하며 실행됩니다. 이 자원은 커널 영역, 힙 영역, 데이터 영역, 코드 영역을 의미합니다.
멀티 프로세스 vs 멀티 스레드
멀티 프로세스와 멀티 스레드는 그 이름에서처럼, 여러 개의 프로세스와 여러 개의 스레드를 뜻합니다.
멀티 프로세스
멀티 프로세스는 여러 프로세스를 동시에 실행하며, 프로세스 간 자원을 공유하지 않기 때문에 프로세스 간 통신 (IPC) 방식을 써야 합니다. 또한, 메모리에 동일한 내용들이 중복해서 존재하기 때문에 메모리에도 부담이 될 수 있습니다.
그러나 한편으로는 자원을 공유하지 않는 덕분에 하나의 프로세스에 문제가 생겨도 다른 프로세스들에는 문제가 발생하지 않는다는 장점이 있기도 합니다.
멀티 스레드
멀티 스레드는 여러 스레드를 동시에 실행하며, 같은 프로세스 내의 자원을 공유합니다. 이 덕분에 멀티 프로세스 방식보다 메모리를 효율적으로 사용할 수 있으며, 서로 통신에 유리합니다.
그러나 자원을 공유하기 때문에 하나의 스레드에서 문제가 생기면 다른 스레드들에도 영향을 끼칠 수 있다는 단점이 있습니다.
Reference
'JSCODE CS > 운영체제 스터디' 카테고리의 다른 글
[JSCODE 운영체제 5주차] 가상 메모리 (1) | 2024.11.28 |
---|---|
[JSCODE 운영체제 4주차] 프로세스 동기화 (0) | 2024.11.21 |
[JSCODE 운영체제 3주차] CPU 스케줄링 (1) | 2024.11.14 |
[JSCODE 운영체제 1주차] 2. 컴퓨터 구조 기본 개념 (1) | 2024.11.01 |
[JSCODE 운영체제 1주차] 1. 운영체제 기본 개념 (3) | 2024.10.31 |