하마코

[CS] 운영체제 - 프로세스, 스레드, 컨택스트 스위칭, 멀티프로세싱/멀티스레딩 본문

DEV/Computer Science

[CS] 운영체제 - 프로세스, 스레드, 컨택스트 스위칭, 멀티프로세싱/멀티스레딩

hamaco.dev 2025. 5. 5. 19:00

안녕하세요! 하마코입니다. 😊

 

저번에 운영체제 1탄에서 가상메모리와 관련된 내용들을 공부해보았는데요!

오늘은 프로그램이 실행될 때 나오는 프로세스, 스레드 등을 알아보려고 합니다.

 

오늘도 열심히 공부해보겠습니다! 


 

프로세스와 스레드

프로세스(Process)는 메모리에 올라와서 실행되고 있는 프로그램입니다.

프로그램은 실행 가능한 코드 자체를 의미해서 프로세스와는 다릅니다. (정적인 파일-exe, py 등)

 

스레드(Thread)는 프로세스 내 작업의 흐름을 지칭합니다.

크롬 창 세 개를 띄우면, 각각의 탭이 독립적인 스레드처럼 작동하여 프로세스 3개가 생깁니다.

프로세스 스레드
코드, 데이터, 스택, 힙 메모리 영역을 기반으로 작업 프로세스 내의 스택 메모리를 제외한 다른 메모리 영역을 프로세스 내의 다른 스레드들과 공유함
다른 프로세스와 격리되어 있어서 서로 통신을 하기 위해 IPC 사용해야함 다른 스레드와 격리되어있지 않아서 바로 통신 가능
한 프로세스에 문제가 생겨도 다른 프로세스에 영향을 끼치지 않음 격리가 되어있지 않아 한 스레드에 문제가 생기면 다른 스레드에도 영향을 끼쳐 스레드로 이루어져있는 프로세스에 영향을 줄 수 있음
생성, 종료에 시간 많이 듦 상대적으로 더 적은 시간이 듦

 

프로그램의 컴파일 과정

프로그램은 컴파일러가 컴파일 과정을 거쳐 컴퓨터가 이해할 수 있는 기계어로 번역되어 실행될 수 있는 파일이 된 것입니다.

  1. 전처리 : 소스코드 주석 제거, #include등의 헤더파일 병합, 매크로 치환 등
  2. 컴파일러 : 오류처리, 코드최적화 작업을 통해 어셈블리어로 변환 (.s)
  3. 어셈블러 : 목적코드(object code)로 변환 (.o)
  4. 링커 : 프로그램 내 있는 라이브러리 함수 등과 결합해 실행파일 만들어짐 (.exe, .out)

프로세스의 메모리 구조

운영체제는 프로세스에 아래 구조를 기반으로 적절한 메모리를 할당합니다.

위부터 스택, 힙, 데이터 영역, 코드 영역으로 나눠집니다.

[출처] Dextutor

 

  • 스택 : 지역변수, 매개변수, 함수가 저장되고 컴파일 시 크기 결정됨 / 함수가 함수를 호출하는 등에 따라 런타임 시에도 크기가 변경됨
  • : 동적 할당 시 사용되며 런타임 시 크기 결정됨
  • 데이터영역 : BSS영역과 Data 영역으로 나뉘고 정적할당에 관한 부분 담당
  • 코드영역 : 소스코드

1> 정적할당

데이터영역, 코드영역에 해당하는 정적할당은 컴파일 단계에서 메모리를 할당하는 것을 의미합니다.

BSS segment, Data segment, code/text segment로 나누어 저장됩니다.

  • BSS segment : 전역변수, static, const로 선언된 변수 중 0으로 초기화 / 초기화 되지 않은 변수
  • Data segment : 전역변수, static, const로 선언된 변수 중 0이 아닌 값으로 초기화된 변수
  • code / text segment : 프로그램 코드

1> 동적할당

런타임 단계에서 메모리를 할당받는 것을 의미합니다.

Stack, Heap으로 나누어 저장됩니다.

  • Stack : 지역변수, 매개변수, 실행되는 함수에 의해 늘어나거나 줄어드는 메모리 영역
    • 함수가 호출될 때마다 호출될 때의 환경 등 특정 정보가 stack에 계속해서 저장됨
  • Heap : 동적으로 할당되는 변수
    • malloc(), free() 함수를 통해 관리 가능. 동적으로 관리되는 자료구조의 경우 힙 영역 사용.

 

PCB와 컨택스트 스위칭

PCB(Process Control BlocK)는 운영체제에서 관리하는 프로세스에 대한 메타데이터를 저장한 데이터 블록입니다.

커널 스택에 저장되며, 각 프로세스가 생성될 때마다 고유의 PCB가 생성되고 프로세스가 종료되면 PCB는 제거됩니다.

* 메타데이터 : 데이터를 설명하는 데이터 (사진 파일이라면, 메타 데이터는 촬영 날짜, 위치, 해상도 등)

* 커널 스택 : 가상 메모리는 사용자공간과 커널공간으로 구분되는데, 모두 스택 자료구조를 기반으로 관리되어 사용자스택, 커널스택이라고도 불림

 

PCB의 구조

[출처] GeeksforGeeks

 

  1. 프로세스 상태 : 대기중, 실행중 등 프로세스의 상태
  2. 프로세스 번호 : 각 프로세스 고유 식별 번호
  3. 프로세스 카운터(PC) : 프로세스에 대해 실행될 다음 명령어 주소에 대한 포인터
  4. 레지스터 : 레지스터 관련 정보
  5. 메모리 제한 : 프로세스의 메모리 관련 정보
  6. 열린 파일 정보 : 프로세스를 위해 열린 파일 목록

컨텍스트 스위칭

컨텍스트 스위칭(context switching)은 PCB를 기반으로 프로세스의 상태(Context)를 저장하고 다시 복원하는 과정입니다.

프로세스가 종료되거나 인터럽트에 의해 발생하며, 프로세스뿐만 아니라 스레드에서도 가능합니다.

실행 중인 프로세스를 저장하고, 다른 프로세스를 불러오는 과정이 진행됩니다.

 

스레드는 프로세스 내에서 실행되는 작업 단위기 때문에, 프로세스의 자원을 공유합니다.

그렇기에, 스레드 간의 컨텍스트 스위칭을 프로세스 간 전환보다 훨씬 가볍게 일어납니다.

 

프로세스의 상태

프로세스의 상태는 크게 [ready suspended]와 [blocked suspended / blocked ⊂ waiting] 상태가 있습니다.

[출처] GeeksforGeeks

 

  • 생성상태 (create/new) : 프로세스가 생성된 상태 ⇢ PCB 할당됨
    • ex. fork() : 부모 프로세스의 주모 공간 그대로 복사하여 새로운 자식 프로세스 생성하는 함수
    • ex. exec() : 새롭게 프로세스를 생성하는 함수
  • 대기상태 (ready) : 처음 프로세스가 생성된 이후 메모리 공간이 충분하면 메모리를 할당받고, 아니면 아닌 상태로 준비큐에 들어가서 대기중인 상태. CPU 스케줄러로부터 CPU 소유권이 넘어오기를 기다리는 상태.
  • 대기중단상태 (ready suspended) : 레디큐가 꽉찬 상태 = 메모리 부족으로 일시 중단된 상태
  • 실행상태 (running) : CPU 소유권과 메모리를 할당받고 명령어를 수행중인 상태
  • 중단상태 (blocked) : 어떤 이벤트가 발생한 이후 기다리며 프로세스가 차단된 상태
  • 일시중단상태 (blocked suspended) : 대기중단상태와 유사하며 중단상태에서 프로세스가 실행되려고 했지만 메모리 부족으로 일시 중단된 상태
  • 종료상태 (terminated/exit) : 프로세스 실행이 완료되어 해당 프로세스에 대한 자원을 반납하며 PCB가 삭제되는 상태. 자식 프로세스에 할당된 자원의 한계치를 넘어서거나, 부모 프로세스가 종료되거나, 사용자가 process.kill 등의 명령어로 프로세스를 종료시킬 때 발생

 

멀티프로세싱과 멀티스레딩

멀티프로세싱은 여러 개의 '프로세스'를 통해 동시에 두 가지 이상의 일을 수행할 수 있는 것을 의미합니다.

특정 프로세스 중 일부에 문제가 발생되더라도 다른 프로세스에 영향을 미치지 않습니다.

예시) 여러 브라우저 창

 

멀티스레딩나의 프로세스 안에서 여러 작업(스레드)을 동시 처리하는 기법입니다.

스레드는 같은 프로세스 안에서 자원을 공유하기 때문에, 가볍고 빠르게 병렬처리가 가능합니다.

예시) 하나의 창 안 여러 탭

 

IPC

IPC(Inter-Process Communication)란 프로세스끼리 데이터를 주고받고 공유데이터를 관리하는 매커니즘입니다.

IPC의 종류로는 공유메모리, 파일, 소켓, 파이프, 메시지 큐가 있습니다.

 

공유메모리

공유메모리란 여러 프로세스가 서로 통신할 수 있도록 메모리를 공유하는 것을 말합니다.

IPC 방식 중, 매개체를 통해 데이터를 주고받는 게 아니라 메모리 자체를 공유해서 동기화하고

불필요한 데이터 복사의 오버헤드가 발생하지 않아 IPC 중 가장 빠른 통신 방법입니다.

 

파일

파일은 디스크에 저장된 데이터를 기반으로 통신하는 것을 의미합니다.

 

소켓

소켓은 네트워크 인터페이스(TCP, UDP, HTTP)를 기반으로 통신하는 것을 의미합니다.

 

파이프

1) 익명파이프 : 프로세스 사이에 FIFO 기반의 통신채널을 만들어 통신하는 것을 의미합니다.

파이프 하나당 단방향 통신이어서 양방향 통신을 하려면 2개의 익명 파이프를 만들어야합니다.

부모, 자식 프로세스 간에만 사용할 수 있고 다른 네트워크 상에서는 사용이 불가능합니다.

2) 명명파이프 : 익명 파이프의 확장된 개념이며 부모, 자식뿐만 아니라 다른 네트워크 상에서도 통신할 수 있는 파이프입니다.

보통 서버, 클라이언트용 파이프를 구분해서 동작합니다.

 

메시지 큐

메세지를 큐 자료구조 형태로 관리하는 버퍼를 만들어 통신하는 것을 의미합니다.

프로세스가 메시지를 보내거나 받기 전에 큐를 초기화하고,

보내는 프로세스(센더)의 메시지는 큐에 복사되어 받는 프로세스(리시버)에 전달됩니다.

 

공유자원과 경쟁상태 그리고 임계영역

공유자원(Shared Resource)은 시스템 안에서 각 프로세스, 스레드가 함께 접근할 수 있는

모니터, 프린터, 메모리, 파일, 데이터 등이 자원이나 변수를 의미합니다.

 

경쟁상태(Race Condition)는 공유 자원을 둘 이상의 프로세스 또는 스레드가 동시에 읽거나 쓰는 상황이며

동시에 접근을 시도할 때의 타이밍이 예상되는 결과 값에 영향을 줄 수 있는 상태를 의미합니다.

 

경쟁 상태를 잘 해결하지 못하면 데이터 정합성, 데이터 무결성을 지키지 못할 수 있는데요.

데이터 정합성이란, 예상되는 데이터의 값과 다른 것을 의미하고 (0원인데 1,000원으로 읽음)

데이터 무결성이란, 데이터의 어떠한 규칙을 위반하면 안 되는 것을 의미합니다. (0원인데 출금)

 

임계영역(Critical Section)은 둘 이상의 프로세스 또는 스레드가 공유자원에 접근할 때

순서 등의 이유로 결과가 달라지는 코드 영역을 의미합니다.

한 번에 둘 이상의 프로세스나 스레드가 들어갈 수 없게 설계됩니다.

// 보통의 임계영역 코드
do {
	lock();
    { 임계 영역 }
    unlock();
}

 


 

 

저번에 가상메모리를 공부했던 것에 이어

오늘은 프로세스, 스레드를 공부해보았습니다.

도움이 되셨다면 좋아요, 댓글 남겨주세요!

 

긴 글 읽어주셔서 감사합니다. :)

HAMACO