본문 바로가기
CS

프로세스와 스레드

by sangyunpark99 2025. 2. 12.

 

"프로세스와 스레드의 차이가 뭘까?"

 

이번글은 프로세스와 스레드에 대해 정리한 글입니다.

아래의 내용은 "기술 면접 대비 CS 전공 핵심 요약집"의 내용을 참고했습니다.

 

프로세스란 무엇일까요?

 

프로세스

컴퓨터에서 실행 중인 하나의 프로그램을 의미하고, 특정 작업을 수행하기 위한 명령어의 집합입니다.

OS는 프로그램을 실행하면, 디스크에 저장된 데이터를 메모리로 로드합니다.  프로세스는 OS로부터 독립된 메모리 영역인(코드, 데이터, 스택, 힙)을 할당받고 다른 프로세스의 메모리 영역에 접근할 수 없습니다.

 

프로세스에 할당된 메모리 영역은 아래 그림과 같습니다.

 

프로세스 메모리 영역 구조는 아래 그림과 같습니다.

각 영역은 어떤 역할을 할까요?

 

스택은 지역 변수, 함수의 매개변수, 반환되는 주소 값 등이 저장됩니다.

높은 주소 값에서 낮은 주소값으로 메모리가 할당되고, 영역 크기는 컴파일 시 결정됩니다.

 

은 동적 메모리 할당이 일어나는 영역입니다. C언어 기준 malloc으로 할당하는 영역입니다.

스택과 반대로 낮은 주소 값에서 높은 주소 값으로 메모리가 할당되고, 영역 크기는 런타임 때 결정됩니다.

 

데이터는 전역 변수, 정적 변수, 배열, 구조체 등이 저장되는 영역입니다. 

데이터 영역은 BSS(Blocked Stated Symbol)영역과 데이터 영역으로 다시 나뉩니다. BSS영역엔 초기화하지 않은 변수를, 데이터 영역은 초기화한 변수를 저장합니다.

 

코드는 실행할 코드가 기계어로 컴파일되어 저장되는 영역으로 텍스트 영역이라고도 합니다.

 

스택 영역과 힙 영역의 빈 메모리 공간은 무엇일까요?

 

스택 영역과 힙 영역 사이에는 빈 메모리 공간이 존재합니다. 스택 영역은 LIFO 방식이고, 높은 주소 값에서 낮은 주소값 순서로 사용합니다. 힙 영역은 FIFO방식이고, 낮은 주소 값에서 높은 주소 값 순서로 사용합니다.

 

메모리 영역을 서로 공유하기 때문에 영역을 서로 침범할 수 있습니다. 흔히 알고 있는 스택 영역이 힙 영역을 침범하는 경우를 스택 오버플로라고 하고, 힙 영역이 스택 영역을 침범하는 경우를 힙 오버플로라고 합니다.

 

 

스레드란 무엇일까요?

 

스레드

스레드는 프로세스에서 실제로 실행되는 흐름 단위를 의미합니다.

프로세스 안에서 프로세스의 메모리 공간을 이용하고, 지역 변수를 저장하는 스택 영역을 할당받습니다. 힙 영역은 다른 스레드와 공유합니다.

 

아까 그림에서 봤던 PCB는 무엇일까요?

 

PCB

OS에서 프로세스를 제어하기 위해 프로세스 정보를 저장하는데, 이것을 PCB(Process Control Block, 프로세스 제어 블록)이라고 합니다. PCB에는 PID(Process ID), 부모 프로세스 PID, 자식 프로세스 PID, 다음으로 실행할 명령어의 주소인 PC(Program Counter), 프로세스 우선순위, 메모리 제한 등을 저장합니다.

 

아래 그림은 PCB에 담긴 정보들을 나타냅니다.

 

프로세스는 어떻게 생성이 될까요?

 

프로세스의 생성

새로운 프로세스는 기존 프로세스에서 fork()함수를 호출해 생성합니다. fork()함수는 함수를 호출한 프로세스를 복사하는 기능이 있습니다.  기존 프로세스는 부모 프로세스, 복사된 프로세스를 자식 프로세스라고 부릅니다.

부모 프로세스에서 fork()함수 호출시 부모 프로세스는 자식 프로세스의 PID 값 자식 프로세스는 0을 반환합니다.

 

그림으로 나타낸 흐름도는 다음과 같습니다.

언제 프로세스가 종료될까요?

 

  • 운영체제의 종료 서비스(exit()) 호출시
  • 프로세스의 실행 시간 또는 특정 이벤트 발생을 기다리는 시간이 제한된 시간을 초과할 시
  • 프로세스가 파일 검색 이나 입출력에 실패할시
  • 오류가 발생하거나 메모리 부족 등이 발생할시

 

자식 프로세스는 언제 종료될까요?
  • 자식 프로세스가 할당된 자원을 초과해 사용할시
  • 자식 프로세스에 할당된 작업이 없을 시

 

프로세스는 CPU에 의해 생성 되고 사라지는 과정을 거칩니다. 흐름이 어떻게 될까요?

 

프로세스 상태도

프로세스는 CPU에 의해서 생성 및 소멸되는 과정을 거칩니다. 이 과정은 생성, 준비, 대기, 실행, 종료라는 5가지 상태로 존재합니다.

5가지 상태의 과정을 그림으로 표현하면 다음과 같습니다.

 

각각 어떤 역할을 할까요?

 

생성은 프로세스가 PCB를 갖고 있지만 OS로부터 승인을 받기 전 상태입니다.

준비는 OS로 부터 승인 받고 준비 큐에서 CPU 할당을 기다리는 상태입니다.

실행은 프로세스가 CPU를 할당 받아 실행하는 상태입니다.

대기는 프로세스가 입출력이나 이벤트 발생을 기다리기 위해 CPU사용을 멈추고 기다리는 상태입니다.

종료는 프로세스 실행을 종료하는 상태입니다.

 

각 상태별 전환시 어떤일이 발생할까요?

 

생성에서 준비상태로 전환시엔 생성 상태의 프로세스가 OS로부터 승인을 받아, 준비 상태의 프로세스가 모여 있는 준비 큐에 추가됩니다.

준비에서 실행으로 전환시엔 준비 큐에 있는 우선순위가 높은 프로세스가 디스패치 되어 실행됩니다.

실행에서 준비로 전환시엔 CPU 독점을 방지하기 위해 타임 아웃 되어 준비 상태로 변경되는 것입니다.

실행에서 대기로 전환시엔 입출력, 이벤트 때문에 대기 상태로 변경됩니다.

대기에서 준비로 전환시엔 입출력, 이벤트가 완료되어 준비 상태로 변경됩니다.

실행에서 종료로 전환시엔 실행 중인 프로세스가 끝나서 종료 상태로 변경됩니다.

 

승인은 CPU를 제외한 다른 자원이 준비되어 해당 프로세스가 준비 상태가 될 수 있도록 OS가 허락하는 것을 의미합니다.

 

프로세스와 스레드가 여러개 있는 환경에선 어떻게 될까요?

 

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

멀티 프로세스와 멀티 스레드에서 제일 많이 다루는 개념은 동시성과 병렬성 입니다.

 

동시성은 무엇일까요?

 

동시성은 하나의 코어(싱글)에서 여러 작업을 번갈아 가면서 처리하는 방식입니다.

CPU는 한번에 하나의 작업만 가능해서 여러 작업을 조금씩 돌아가면서 처리합니다.

이렇게 하나의 CPU에서 여러 작업을 번갈아 가면서 처리하기 위해 처리 중인 작업을 교체하는 것을 콘텍스트 스위칭이라고 합니다.

 

병렬성은 무엇일까요?

 

CPU가 여러개 있어 CPU에서 각 작업을 동시에 처리하는 방식입니다.

물리적인 시간 관점에서 동시에 여러 작업이 처리됩니다.

 

동시성과 병렬성을 그림으로 나타내면 다음과 같습니다.

 

병렬성은 멀티 프로세스 방식에서 사용됩니다.

멀티 프로세스는 무엇일까요?

 

멀티 프로세스

멀티 프로세스는 응용 프로그램 하나를 여러 프로세스로 구성하는 것을 의미합니다.

하나의 프로세스가 죽어도 다른 프로세스에 영향을 주지 않는 구조입니다. 이러한 구조 때문에 응용 프로그램을 프로세스 하나로 구성되는 것보다 여러 개로 구성하는 것이 안정적입니다.

 

단일 코어 환경에서 CPU는 하나의 작업만 처리할 수 있기 때문에, 여러 프로세스를 처리하기 위해선 콘텍스트 스위칭 작업이 필요합니다.

또한, 멀티코어 환경에서도 프로세스 개수가 코어 개수보다 많거나, 다른 코어에서 실행될 경우 컨텍스트 스위칭이 발생할 수 있습니다.

 

컨텍스트 스위칭 작업은 비용이 안드는 작업일까요?

 

컨텍스트 스위칭 작업이 이루어질때, CPU에서 기존에 처리하던 프로세스가 할당받은 메모리 영역을 다른 프로세스가 사용할 수 있도록 교체하면서 시간과 메모리가 필요하게 됩니다. 이를 오버헤드라고 부릅니다.

 

프로세스에서 자원 공유가 가능할까요?

 

프로세스는 독립적인 메모리를 할당 받기 때문에, 프로세스 간에 공유할 자원이 있다면 IPC(Inter Process Communication)을 통해 프로세스 간에 자원을 공유해야 합니다. 이러한 작업 때문에 공유할 메모리를 직접 참조하는 것에 비해서는 비효율적입니다.

 

멀티 프로세스 구조를 이미지로 나타내면 다음과 같습니다.

 

멀티 스레드

스레드를 여러 개 생성해 스레드들이 다른 작업을 처리하는 것을 의미합니다.

멀티 스레드는 프로세스와 달리 스레드 간 힙, 데이터, 코드 영역을 공유합니다. 따라서, 프로세스에 비해 컨텍스트 스위칭할 때 오버헤드가 적게 발생하고, IPC를 사용하지 않아도 되므로 속도가 빠릅니다.

 

스레드에도 제어 정보를 저장할까요?

 

TCB(Thread Control Block)

스레드의 상태와 관련된 정보를 저장하는 데이터 구조입니다. 저장된 정보로는 고유 식별자, 레지스터 값, 스택 포인터, 스케줄링 정보가 포함되어 있고, 스레드는 동일한 프로세스 내에서 실행되므로 프로세스의 PCB와 관련된 리소스를 공유합니다.

즉, 여러 스레드가 하나의 PCB를 공유하고,  각 스레드는 자체 TCB를 가지고 자신의 상태 관리합니다.

 

주의할 점은 스레드의 스택(Stack) 영역은 독립적이지만, 힙(Heap) 영역과 전역 변수는 공유되므로, 공유 자원에 대한 동기화가 필수적입니다.

 

멀티 스레드 구조의 이미지는 다음과 같습니다.

멀티 프로세스와 멀티 스레드 둘다 어떤 작업이 발생할까요?

 

컨텍스트 스위칭

CPU는 하나의 프로세스만 처리할 수 있으므로 멀티 프로세스를 처리하기 위해선 CPU 스케줄러에 의해 인터럽트가 발생하면서 콘텍스트 스위칭이 이뤄집니다. 콘텍스트는 CPU가 처리하는 프로세스의 정보를 의미합니다. 즉, 멀티 프로세스 및 멀티 스레드 환경에서 CPU가 처리 중인 프로세스 및 스레드 정보를 바꾸는 것이 컨텍스트 스위칭 입니다.

 

인터럽트는 입출력 관련 이벤트가 발생하거나 예외 상황이 발생할 때 CPU에게 예외사항 처리를 요청하는 것을 의미합니다.

 

컨텍스트 스위칭을 그림으로 나타내면 아래와 같습니다.

그림에서 처리 중인 프로세스는 P1이고, 처리해야 할 프로세스는 P2입니다. 흐름은 다음과 같습니다.

  • CPU가 P1을 처리하던 중 OS에 의해 인터럽트가 발생합니다.
  • P1은 유휴 상태(idle)로 변하고 스케줄러는 레지스터에 있는 처리 중인 작업 정보를 P1의 PCB에 저장합니다.
  • P2의 PCB에 있는 정보를 가져와 레지스터에 로드하고 CPU는 P2를 처리하기 시작합니다.
  • P1의 정보를 P1의 PCB에 저장하고, P2의 상태를 P2의 PCB에 저장된 정보를 레지스터에 로드하는 동안 CPU는 휴식하게 됩니다. 이렇게 어떤 처리를 할시 처리 시간과 메모리가 소요될 경우를 오버헤드라고 말합니다.
어떻게 프로세스가 중간에 변경 되어도 이전에 실행하던 코드를 이어서 실행할 수 있을까요?

 

PCB에 프로그램 카운터와 스택 포인터 값이 저장되어 있기 때문에 가능합니다.

프로그램 카운터는 프로세스가 이어서 처리해야 하는 명령어의 주소 값을 나타내고, 스택 포인터는 스택 영역에서 데이터가 채워진 가장 높은 주소값을 나타냅니다. 이러한 정보를 사용해 컨텍스트 스위칭을 원할하게 진행합니다.

 

프로세스끼리도 자원 공유가 필요할거 같은데 가능할까요?

IPC

프로세스는 작업을 진행하면서 자원을 공유해야 할 때 IPC를 하게 됩니다.

IPC는 Inter Process Communication으로, 프로세스 간에 자원을 공유하는 방식을 나타냅니다. 대표적으로 5가지 방식이 존재합니다.

 

1. 공유 메모리

프로세스 간에 공유가 되는 메모리는 구성해 자원을 공유합니다. 여러 프로세스에서 접근 가능하므로 동기화 문제가 발생할 수 있습니다.

 

2. 소켓

네트워크 소켓을 통해 프로세스간 통신을 할 수 있습니다.

 

3. 세마포어

접근하는 프로세스를 제어함으로 공유 자원을 관리합니다.

 

 

4. 파이프

FIFO 형태의 메모리 파이프를 사용해 프로세스간 자원을 공유하는 방식입니다.

파이프는 단방향 통신이이므로 읽기 또는 쓰기 중 하나만 가능합니다. 양방향 통신을 하기 위해선 읽기 파이프와 쓰기 파이프를 각각 생성해야 합니다.

5. 메시지 큐

FIFO 형태의 큐 자료구조를 사용해 프로세스 간 메시지를 주고 받습니다.

 

멀티 프로세스 및 멀티 스레드 환경에서 공유되는 자원의 일관성을 어떻게 보존해주나요?

 

프로세스 동기화

 

공유 자원에 접근할 수 있고 접근 순서에 따라 결과가 달라지는 코드 영역을 임계영역이라 합니다.

임계 영역에서 경쟁 상태가 발생하고, 이를 방지하기 위해선 여러 프로세스가 공유 자원에 접근해도 데이터의 일관성을 유지할 수 있도록 동기화해야 합니다.

 

어떤 동기화 기법이 있을까요?

 

뮤텍스

락을 가진 프로세스만이 공유 자원에 접근할 수 있게 해주는 방법입니다.

뮤텍스를 그림을 표현하면 다음과 같습니다.

임계 영역에 먼저 접근한 프로세스가 임계 영역에 락을 걸면 다른 프로세스들은 해당 프로세스가 락을 해제하기 전까지 대기해야 합니다.

이러한 흐름을 락킹 매커니즘이라고 합니다. 

 

락이 걸려있어 임계 영역에 접근하지 못한 프로세스는 뭘하고 있을까요?

 

락을 얻기 위해 기다리는 동안 락이 풀렸는지 반복문을 돌면서 확인합니다.

이를 바쁜 대기의 한 종류인 스핀락이라고 합니다. 스핀락은 락을 얻기 위해 프로세스가 반복문을 돌면서 기다리는 것을 의미합니다.

프로세스가 대기 상태로 빠지지 않고 반복문을 통해 락여부를 파악하므로 빠르게 교체될 수 있습니다.

 

 

바쁜 대기는 프로세스가 공유 자원에 접근할 수 있는 권한을 얻을 때까지 확인하는 과정을 말합니다.

 

세마포어

공유 자원에 접근할 수 있는 프로세스의 수를 정해 접근을 제어하는 방법입니다.

세마포어를 그림을 표현하면 다음과 같습니다.

 

임계 영역에 접근할 수 있는 키 n개를 지정하고 이 중 하나를 가진 프로세스만이 임계 영역에 접근할 수 있습니다.

공유 자원에 접근한 프로세스가 접근을 해제하는 경우 다른 프로세스가 접근할 수 있도록 신호를 보낸다는 의미에서 시그널링 매커니즘이라고도 합니다.

 

 

동기화 기법을 통해 발생하는 문제는 없을까요?

 

교착 상태

교착 상태는 2개 이상의 프로세스가 각각 자원을 가지고 있으면서 서로의 자원을 요구하며 기다리는 상태입니다.

 

교착 상태는 4가지 필요 충분 조건이 있습니다.

  • 상호 배제 : 하나의 공유 자원에 하나의 프로세스만 접근 가능합니다.
  • 점유와 대기 : 프로세스가 최소 하나의 자원을 점유하고 있는 상태에서 추가로 다른 프로세스에서 사용중인 자원을 점유하기 위해 대기합니다.
  • 비선점 : 다른 프로세스에 할당된 자원을 뺏지 못합니다.
  • 환형 대기 : 프로세스가 자신의 자원을 점유하면서 앞이나 뒤에 있는 프로세스의 자원을 요구합니다.

 

교착 상태를 해결하려면 어떻게 할 수 있을까요?

 

4가지 필요 충분 조건 중 한가지를 제거 하면 해결할 수 있습니다.

  • 상호 배제 부정 : 여러 프로세스가 하나의 공유 자원을 사용할 수 있습니다.
  • 점유와 대기 부정 : 프로세스가 실행되기전 필요한 모든 자원을 할당해 대기를 없애고, 프로세스가 자원을 점유하지 않은 상태에서만 자원을 요구하게 합니다.
  • 비선점 부정 : 자원을 점유한 프로세스가 다른 자원을 요구시 점유한 자원을 반납하게 합니다.
  • 환형 대기 부정 : 자원을 선형 순서로 정렬해 고유 번호를 할당합니다. 각 프로세스에서 요구할 수 있는 번호의 방향을 정해서 한쪽 방향으로만 자원을 요구하게 합니다.

 

좀비 프로세스 고아 프로세스

자식 프로세스가 종료되었지만 부모 프로세스가 종료된 자식프로세스를 회수 하지 않은 경우에 남겨진 자식 프로세스를 좀비 프로세스라고 합니다.  자식 프로세스가 종료될 때 부모 프로세스에 SIGCHLD라는 신호를 보내면 부모 프로세스에서 wait()함수를 호출해 자식 프로세스의 정보를 받고 자원을 회수합니다.

 

부모 프로세스가 자식 프로세스보다 먼저 종료되는 경우에 자식 프로세스를 고아 프로세스라고 합니다.

이런 경우 자식 프로세스의 부모 PID를 init프로세스의 PID인 1로 변경해 줍니다. init프로세스는 부팅시 시 가장 먼저 실행되는 프로세스 입니다. 이후 고아 프로세스가 작업이 종료되는 경우 init 프로세스가 고아 프로세스의 자원을 회수함으로 좀비 프로세스가 되는 것을 방지합니다.

 

프로세스는 어떠한 방법으로 종료가 될까요?

 

프로세스의 종료

프로세스가 종료될 때, 운영체제는 종료 상태를 기록하여 프로세스가 어떻게 종료되었는지 확인할 수 있도록 합니다.

종료 상태는 

 

정상 종료 (Normal Termination)

  • 프로세스가 작업을 완료하고 더 이상 실행할 작업이 없는 경우 종료됩니다.
  • 종료 코드(Exit Code)를 반환하며 운영 체제에 종료 신호를 보냅니다.

 

명시적인 종료 요청 (Explicit Termination)

  • 프로세스가 시그널(Signal) 을 통해 운영 체제 또는 외부 요인으로부터 종료 요청을 받을 때 발생합니다.
  • 프로세스는 시그널을 수신하고 종료 작업을 수행한 후 종료됩니다.

 

다른 프로세스에 의한 종료 (Parent Process Control)

  • 부모 프로세스가 자식 프로세스를 종료할 수 있습니다.
  • 자식 프로세스가 종료될 때, 부모 프로세스는 wait()을 통해 종료 상태를 수집합니다.

 

시스템 종료 (System Shutdown)

  • 운영 체제가 종료(Shutdown)되거나 재부팅(Reboot)될 때, 실행 중인 모든 프로세스가 종료됩니다.
  • 운영 체제는 종료 시그널(Signal) 또는 시스템 호출을 통해 모든 프로세스를 종료합니다.

 

일반적으로 0은 정상 종료, 0이 아닌 값은 오류 또는 비정상 종료를 의미합니다.

 

 

 

데몬 프로세스

백그라운드에서 실행되는 프로세스로, 특정 사용자 세션과 독립적으로 실행되며, 시스템의 전반적인 서비스 제공 및 유지 관리 역할을 수행합니다.

데몬 프로세스는 주로 시스템 서비스나 백엔드 작업을 수행하며, 대표적인 역할은 다음과 같습니다.

 

시스템 서비스 관리

  • 시스템의 기본 기능을 유지하는 데 필요한 작업을 수행합니다.
  • cron(스케줄러), syslogd(로그 관리)

네트워크 서비스 운영

  • 서버와 클라이언트 간의 통신을 처리하는 네트워크 서비스 제공합니다.
  • sshd(SSH 서버), httpd(Apache 웹 서버), nginx(웹 서버), mysqld(데이터베이스 서버)

자동화 및 스케줄링

  • 특정 시간이나 조건에 맞춰 자동 실행되는 작업을 수행합니다.
  • crond(예약 작업 실행), atd(일회성 작업 실행)

백그라운드 데이터 처리

  • 실시간으로 데이터를 모니터링하고, 이벤트 발생 시 특정 동작 수행합니다.
  • auditd(보안 감사 로그 기록), systemd(시스템 서비스 관리)

'CS' 카테고리의 다른 글

[네트워크] TCP 제어 방법  (0) 2025.02.15
[DB] 트랜잭션  (0) 2025.02.09
[네트워크]TCP/IP & HandShaking  (0) 2025.02.01
[네트워크] OSI 7계층  (2) 2025.01.27
[운영체제] 스케줄링  (0) 2024.11.26