본문 바로가기
CS 공부/컴퓨터 구조, 운영체제

운영체제(2) - 프로세스와 스레드

by 프롭 2026. 2. 13.

 

프로세스 개요

 

실행 중인 프로그램을 프로세스라 한다. 윈도우에서 작업 관리자의 [프로세스] 탭에서 확인할 수 있고, 유닉스 체계의 운영체제에서는 ps명령어로 확인할 수 있다.

 

사용자가 볼 수 있는 공간에서 실행되는 프로세스도 있지만, 보이지 않는 공간에서 실행되는 프로세스도 있다. 전자는 사용자가 보는 앞에서 실행되는 포그라운 프로세스(forefround process)라 하고, 후자는 사용자가 보지 못하는 뒤편에서 실행되는 백그라운드 프로세스(background process)라 한다.

 

백그라운 프로세스 중에는 사용자와 상호작용할 수 있는 것도 있지만 상호작용하지 않고 정해진 일만 수행하는 것도 있다. 이를 유닉스 체계의 운영체제에서는 데몬(daemon)이라 부르고, 윈도우 운영체제에서는 서비스(service)라 부른다.

 

프로세스 제어 블록

 

모든 프로세스는 실행을 위해 CPU를 필요로 하지만, CPU 자원은 한정되어 있다. 그렇기에 인터럽트를 발생시켜 차례대로 돌아가며 동작한다.

 

운영체제는 빠르게 번갈아 수행되는 프로세스의 실행 순서를 관리하고, 프로세스에 CPU를 비롯한 자원을 배분한다. 이를 위해 운영체제는 프로세스 제어 블록(PCB : Process Control Block)을 이용한다.

 

프로세스 제어블록은 프로세스를 식별하기 위해 필요한 관련 정보를 저장하는 자료구조다. PCB는 커널 영역에 생성된다. 운영체제는 수많은 프로세스들 사이에서 PCB로 특정 프로세스를 식별하고 해당 프로세스를 처리하는 데 필요한 정보를 판단한다. PCB는 프로세스 생성 시에 만들어지고 실행이 끝나면 폐기된다. 다음으로 PCB에 담기는 정보들을 알아보자.

 

  • 프로세스 ID
    • 프로세스 ID(PID)는 특정 프로세스를 식별하기 위해 부여하는 고유번호다. 같은 일을 수행하는 프로그램이라 할지라도 두 번 실행하면 PID가 다른 두 개의 프로세스가 생성된다.
  • 레지스터 값
    • 프로세스는 자신의 실행 차례가 돌아오면 이전 사용했던 레지스터의 중간 값들을 모두 복원한다. 그래서 PCB 안에는 해당 프로세스가 실행하며 사용했던 프로그램 카운터를 비롯한 레지스터 값들이 담긴다.
  • 프로세스 상태
    • 현재 프로세스가 어떤 상태인지 PCB에 기록되어야 한다. 입출력 장치, CPU를 사용하기 위해 기다리고 있는지 혹은 사용하고 있는 상태인지 등의 상태 정보가 저장된다.
  • CPU 스케줄링 정보
    • 프로세스가 언제, 어떤 순서로 CPU를 할당받을지에 대한 정보도 PCB에 기록된다.
  • 메모리 관리 정보
    • 프로세스마다 메모리에 저장된 위치가 다르다. PCB에는 프로세스가 어느 주소에 저장되어 있는지에 대한 정보가 있어야 한다. 베이스 레지스터, 한계 레지스터 값과 같은 정보가 담기며 프로세스의 주소를 알기 위한 주요 정보 중 하나인 페이지 테이블 정보도 PCB에 담긴다.
  • 사용한 파일과 입출력 장치 목록
    • 프로세스 실행 과정에서 특정 입출력장치나 파일을 사용하면 PCB에 해당 내용이 명시된다.

 

문맥 교환

 

하나의 프로세스 수행을 재개하기 위해 기억해야 할 정보를 문맥이라 한다. 하나의 프로세스 문맥은 해당 프로세스의 PCB에 표현되어 있다. PCB에 기록되는 정보들을 문맥이래 봐도 무방하다. 실행 문맥을 잘 기억해두면 언제든 해당 프로세스의 실행을 재개할 수 있기에 프로세스가 예기치 못한 상황이 발생하여 인터럽트가 발생하면 운영체제는 해당 프로세스의 PCB에 문백을 백업한다.

 

기존 프로세스의 문맥을 PCB에 백업하고, 새로운 프로세스를 실행하기 위해 문맥을 PCB로부터 복구하여 새로운 프로세스를 실행하는 것을 문맥 교환이라 한다. 문맥 교환은 여러 프로세스가 끊임없이 빠르게 번갈아 가며 실행되는 원리다. 문맥 교환이 자주 일어나면 프로세스는 그만큼 빨리 번갈아가며 수행되기에 우리는 프로세스들이 동시에 실행되는 것처럼 보인다.

 

프로세스의 메모리 영역

프로세스가 생성되면 커널 영역에 PCB가 생성된다 했다. 그렇다면 사용자 영역에는 어떻게 배치될까? 프로세스는 사용자 영역에 크게 코드 영역, 데이터 영역, 힙 영역, 스택 영역으로 나뉘어 저장된다.

 

  • 코드 영역
    • 코드 영역은 텍스트 영역이라고도 부른다. 실행할 수 있는 코드, 즉 기계어로 이루어진 명령어가 저장된다. 데이터가 아닌 CPU가 실행할 명령어가 담겨있기에 쓰기가 금지되어 있어 읽기 전용 공간이다.
  • 데이터 영역
    • 데이터 영역은 잠깐 썼다가 없어질 데이터가 아닌 프로그램이 실행되는 동안 유지할 데이터가 저장된 공간이다. 이러한 데이터로는 전역 변수가 대표적이다

 

코드 영역과 데이터 영역은 크기가 변하지 않는다. 이러한 크기가 고정된 영역을 정적 할당 영역이라 부른다. 반면 힙 영역과 스택 영역은 프로세스 실행 과정에서 그 크기가 변할 수 있는 영역이다. 그래서 이를 동적 할당 영역이라 부른다.

 

  • 힙 영역
    • 힙 영역은 프로그램을 만드는 사용자가 직접 할당할 수 있는 공간이다. 힙 영역에 메모리 공간을 할당했다면 언젠가는 해당 공간을 반환해야 한다. 메모리 공간을 반환하지 않는다면 할당한 공간은 메모리에 내에 계속 남아 메모리 낭비를 초래한다. 이를 메모리 누수라 한다.
  • 스택 영역
    • 스택 영역은 일식적으로 저장하는 공간이다. 데이터 영역에 담기는 값과 달리 잠깐 쓰다 말 값들이 저장되는 공간이다. 이런 데이터로는 함수의 실행이 끝나면 사라지는 매개 변수, 지역 변수가 대표적이다.

 

힙 영역과 스택 영역은 동적 할당 영역이라 했다. 그래서 일반적으로 새로 할당되는 주소가 겹쳐지지 않게 힙 영역은 메모리의 낮은 주소에서 높은 주소로 스택 영역은 높은 주소에서 낮은 주소로 할당된다.

 

프로세스 상태와 계층 구조

 

프로세스 상태

 

컴퓨터에서 여러 프로세스들이 빠르게 번갈아 가면서 실행된다고 했다. 그 과정에서 하나의 프로세스는 여러 상태를 거치며 실행된다. 그리고 운영체제는 프로세스의 상태를 PCB를 통해 인식하고 관리한다. 프로세스가 가지는 대표적인 상태는 아래와 같다

 

  • 생성 상태
    • 프로세스를 생성 중인 상태를 생성 상태라 한다. 이제 막 메모리에 적재되어 PCB를 할당받은 상태를 말한다. 생성 상태를 거쳐 실행할 준비가 완료된 프로레스는 곧바로 실행되지 않고 준비 상태가 되어 CPU의 할당을 기다린다.
  • 준비 상태
    • 준비 상태는 당장이라도 CPU를 할당받아 실행할 수 있지만, 아직 자신의 차례가 아니기에 기다리고 있는 상태다. 준비 상태 프로세스는 차례가 되면 CPU를 할당받아 실행 상태가 된다.
  • 실행 상태
    • 실행 상태는 CPU를 할당받아 실행 중인 상태를 의미한다. 실행 상태인 프로세스는 할당된 일정 시간 동안만 CPu를 사용할 수 있다. 이따 할당된 시간을 모두 사용하면 다시 준비 상태가 되고, 실행 도중 입출력 장치의 작업이 끝날 때까지 기다려야 한다면 대기 상태가 된다.
  • 대기 상태
    • 프로세스는 실행 도중 입출력장치를 사용하는 경우가 있다. 입출력 작업은 CPU에 비해 처리 속도가 느리기에, 입출력 작업을 요청한 프로세스는 입출력 장치가 입출력을 끝낼 때까지 기다려야 한다. 이렇게 입출력장치의 기다리는 상태는 대기 상태라 한다. 작업이 완료되면 다시 준비 상태로 CPU 할당을 기다린다.
  • 종료 상태
    • 종료 상태는 프로세스가 종료된 상태다. 프로세스가 종료되면 운영체제는 PCB와 프로세스가 사용한 메모리를 정리한다.

 

프로세스 계층 구조

 

프로세스는 실행 도중 시스템 호출을 통해 다른 프로세스를 생성할 수 있다. 이때 새 프로세스를 생성한 프로세스를 부모 프로세스, 부모 프로세스에 의해 생성된 프로세스를 자식 프로세스라 한다.

 

부모 프로세스와 자식 프로세스는 다른 프로세스이기에 각기 다른 PID를 가진다. 일부 운영체제에서는 자식 프로세스의 PCB에 부모 프로세스의 PID인 PPID(Parent PID)를 기록하기도 한다.

 

많은 운영체제는 이처럼 프로세스가 프로세스를 낳는 계층적인 구조로써 프로세스들을 관리한다. 컴퓨터가 부팅될 때 실행되는 최초의 프로세스들을 생성하고, 생성된 자식 프로세스들이 새로운 프로세스들을 낳는 형식으로 여러 프로세스가 동시에 실행된다. 이를 프로세스 계층 구조라 한다.

 

프로세스 생성 기법

 

부모 프로세스를 통해 생성된 자식 프로세스들은 fork와 exec를 통해 실행된다. 정확하게, 부모 프로세스는 fork를 통해 자신의 복사본을 자식 프로세스로 생성해 내고(복사된 자식 프로세스라 할지라도 PID 값이나 저장된 메모리 위치는 다르다), 만들어진 복사본(자식 프로세스)은 exec를 통해 자신의 메모리 공간을 다른 프로그램으로 교체한다. exec를 호출하면 코드 영역과 데이터 영역의 내용이 실행할 프로그램의 내용으로 바뀌고, 나머지 영역은 초기화된다. 즉, 부모가 자식 프로세스를 실행하며 프로세스 계층 구조를 이루는 과정은 fork와 exec가 반복되는 과정이다.

 

추가로 부모 프로세스가 자식 프로세스를 fork 한 뒤 부모 프로세스, 자식 프로세스 누구도 exec를 호출하지 않는 경우도 있는데 이러한 경우 둘은 같은 코드를 병행하여 실행하는 프로세스가 된다.

 

스레드

 

프로세스와 스레드

 

스레드란 프로세스를 구성하는 실행의 흐름 단위다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있고 스레드를 이용하면 하나의 프로세스에서 여러 부분을 동시에 실행할 수 있다.

 

한 번에 하나의 부분만 실행되는 프로세스를 단일 스레드 프로세스라 볼 수 있다. 하지만 스레드라는 개념으로 하나의 프로세스가 한 번에 여러 일을 동시에 처리할 수 있게 되었다. 즉, 여러 명령어를 동시에 실행할 수 있게 된 것이다.

 

스레드는 프로세스 내에서 각기 다른 스레드 ID, 프로그램 카운터 값을 비롯한 레지스터 값, 스택으로 구성된다. 각자 값을 가지기에 각기 다른 코드를 실행할 수 있다.

 

여기서 중요한 점은 프로세스의 스레드들은 실행에 필요한 최소한의 정보만을 유지한 채 프로세스 자원을 공유하며 실행된다는 점이다. 최근 많은 운영체제는 CPU에 처리할 작업을 전달할 때 프로세스가 아닌 스레드 단위로 전달한다.

 

멀티 프로세스와 멀티 스레드

 

여러 프로세스를 동시에 실행하는 것을 멀티 프로세스, 그리고 여러 스레드로 프로세스를 동시에 실행하는 것을 멀티 스레드라 한다.

 

단일 스레드 프로세스 여러 개를 실행하는 것과 하나의 프로세스를 여러 스레드로 동시에 실행하는 것은 무엇이 다를까? 여기는 큰 차이점이 있다. 프로세스끼리는 기본적으로 자원으로 공유하지 않지만, 스레드끼리는 같은 프로세스 내의 자원을 공유한다는 점이다.

 

프로세스를 fork 하여 같은 작업을 하는 동일한 프로세스 두 개를 동시에 실행하면 코드 영역, 데이터 영역, 힙 영역 등을 비롯한 모든 자원이 복제되어 메모리에 적재된다. 한마디로 PID, 저장된 메모리 주소를 제외한 모든 것이 통째로 두 개의 프로세스가 메모리에 적재되는 것이다. 이는 메모리 낭비다. 같은 프로그램을 실행하기 위한 동일한 내용들이 중복해서 존재하는 것이기 때문이다.

 

이에 반해 스레드들은 가지고 있는 자원을 공유하기에 동일한 주소 공간의 코드, 데이터, 힙 영역을 공유하고 열린 파일과 같은 프로세스 자원을 공유한다. 여러 프로세스를 병행 실행하는 것보다 메모리를 효율적으로 사용할 수 있다. 추가로 자원을 공유하기에 서로 협력과 통신에 유리하다.

 

프로세스의 자원을 공유한다는 특성은 때론 단점이 될 수 있는데, 멀티 스레드 환경에서 하나의 스레드에 문제가 생기면 프로세스 전체에 문제가 생길 수 있다. 모든 스레드는 자원으로 공유하고 하나의 스레드에 문제가 생기면 다른 스레드도 영향을 받기 때문이다.

 

+ 프로세스 간 통신

프로세스끼리는 기본적으로 자원을 공유하지 않지만 충분히 자원으로 공유하고 데이터를 주고받을 수 있다. 프로세스 간의 자원을 공유하고 데이터를 주고받는 것을 프로세스 간 통신(IPC : Inter-Process Communication)이라 한다.

프로세스들은 서로 공유하는 메모리 영역을 두어 데이터를 주고받을 수 있다. 프로세스들이 공유할 수 있는 메모리 영역을 공유 메모리라 한다. 이 외에도 프로세스들은 소켓, 파이프 등을 통해 통신할 수 있다.