본문 바로가기

Computer Structure & Operating System/2025 version

Computer Structure & OS(10) - 프로세스와 스레드

728x90
반응형

1) 프로세스 개요

    1-1) 프로세스 직접 확인하기

    1-2) 프로세스 제어 블록

    1-3) 문맥 교환

    1-4) 프로세스의 메모리 영역

2) 프로세스 상태와 계층 구조

    2-1) 프로세스 상태
    2-2) 프로세스 계층 구조

    2-3) 프로세스 생성 기법

3) 스레드

    3-1) 프로세스와 스레드
    3-2) 멀티프로세스와 멀티스레드

 

 

 

 

 

 

 

1) 프로세스 개요

1-1) 프로세스 직접 확인하기

  • 프로세스(process) : 실행 중인 프로그램
  • 프로그램은 실행되기 전까지는 그저 보조기억장치에 있는 데이터 덩어리일 뿐이지만, 보조기억장치에 저장된 프로그램을 메모리에 적재하고 실행하는 순간 그 프로그램은 프로세스가 됨(이 과정을 '프로세스를 생성한다'라고 표현함)
  • 프로세스의 종류에는 포그라운드 프로세스와 백그라운드 프로세스가 있음
    • 포그라운드 프로세스(foreground process) : 사용자가 볼 수 있는 공간에서 실행되는 프로세스
    • 백그라운드 프로세스(background process) : 사용자가 보지 못하는 뒤편에서 실행되는 프로세스
  • 백그라운드 프로세스 중에는 사용자와 직접 상호작용할 수 있는 백그라운드 프로세스도 있지만, 사용자와 상호작용하지 않고 그저 묵묵히 정해진 일만 수행하는 백그라운드 프로세스도 있음
  • 백그라운드 프로세스를 유닉스 체계의 운영체제에서는 데몬(daemon)이라고 부르고, 윈도우 운영체제에서는 서비스(service)라고 부름

 

1-2) 프로세스 제어 블록

  • 프로세스 제어 블록(PCB; Process Control Block) : 프로세스와 관련된 정보를 저장하는 자료 구조(즉, PCB에는 해당 프로세스를 식별하기 위해 꼭 필요한 정보들이 저장됨)
  • 운영체제는 프로세스 제어 블록을 통해 여러 프로세스를 관리함
  • PCB에 담기는 정보
    • 프로세스 ID(PID; Process ID) : 특정 프로세스를 식별하기 위해 부여하는 고유한 번호
    • 레지스터 값 : 프로세스는 자신의 실행 차례가 돌아오면 이전까지 사용했던 레지스터의 중간값들을 모두 복원하여 이전까지 진행했던 작업들을 그대로 이어 실행할 수 있는데 이 때문에 PCB 안에는 해당 프로세스가 실행하며 사용했던 프로그램 카운터를 비롯한 레지스터 값들이 담김
    • 프로세스 상태 : 현재 프로세스가 어떤 상태(현재 프로세스가 입출력장치를 사용하기 위해 기다리고 있는 상태인지, CPU를 사용하기 위해 기다리고 있는 상태인지, 아니면 CPU를 이용하고 있는 상태인지 등)인지 PCB에 기록되어야 함
    • CPU 스케줄링 정보 : 프로세스가 언제, 어떤 순서로 CPU를 할당받을지에 대한 정보도 PCB에 기록됨
    • 메모리 관리 정보 : 프로세스마다 메모리에 저장된 위치가 다른데 이 때문에 PCB에는 프로세스가 어느 주소에 저장되어 있는지에 대한 정보(베이스 레지스터, 한계 레지스터 값과 같은 정보들)가 있어야 함(추가로 프로세스의 주소를 알기 위한 또 다른 중요 정보 중 하나인 페이지 테이블 정보도 PCB에 담김)
    • 사용한 파일과 입출력장치 목록 : 프로세스가 실행 과정에서 특정 입출력장치나 파일을 사용하면 PCB에 해당 내용이 명시됨(즉, 어떤 입출력장치가 이 프로세스에 할당되었는지, 어떤 파일들을 열었는지에 대한 정보들이 PCB에 기록됨)

 

1-3) 문맥 교환

  • 문맥(context) : 하나의 프로세스 수행을 재개하기 위해 기억해야 할 정보
  • 하나의 프로세스 문맥은 해당 프로세스의 PCB에 표현되어 있음
  • 문맥 교환(context switching) : 기존 프로세스 문맥을 PCB에 백업하고, 새로운 프로세스를 실행하기 위해 문맥을 PCB로부터 복구하여 새로운 프로세스를 실행하는 것을 의미함(즉, 문맥 교환은 프로세스 간에 실행을 전환하는 것을 의미함)
  • 문맥 교환은 여러 프로세스가 끊임없이 빠르게 번갈아 가며 실행되는 원리로 문맥 교환이 자주 일어나면 프로세스는 그만큼 빨리 번갈아 가며 수행되기 때문에 마치 프로세스들이 동시에 실행되는 것처럼 보임
  • 문맥 교환을 너무 자주하면 오버헤드가 발생할 수 있기 때문에 문맥 교환이 자주 일어난다고 해서 반드시 좋은 것은 아님

 

1-4) 프로세스의 메모리 영역

  • 하나의 프로세스는 사용자 영역에 크게 코드 영역, 데이터 영역, 힙 영역, 스택 영역으로 나뉘어 저장(혹은 배치)됨
    • 코드 영역(code segment) : 텍스트 영역(text segment)이라고도 부르는데 이 곳에는 말 그대로 실행할 수 있는 코드, 즉 기계어로 이루어진 명령어가 저장됨(코드 영역에는 데이터가 아닌 CPU가 실행할 명령어가 담겨 있기 때문에 쓰기가 금지되어 있는데 즉, 코드 영역은 읽기 전용 공간임)
    • 데이터 영역(data segment) : 잠깐 썼다가 없앨 데이터가 아닌 프로그램이 실행되는 동안 유지할 데이터(대표적으로 전역 변수가 해당됨)가 저장되는 공간
    • 힙 영역(heap segment) : 프로그램을 만드는 사용자, 즉 프로그래머가 직접 할당할 수 있는 저장 공간(힙 영역에 메모리 공간을 할당했다면 언젠가는 해당 공간을 반환해야 하는데 만일 메모리 공간을 반환하지 않는다면 할당한 공간은 메모리 내에 계속 남아 메모리 낭비를 초래하게 되는데 이러한 문제를 일명 메모리 누수;memory leak이라고 함)
    • 스택 영역(stack segment) : 데이터를 일시적으로 저장하는 공간으로 데이터 영역에 담기는 값과는 달리 잠깐 쓰다가 말 값들(함수의 실행이 끝나면 사라지는 매개 변수, 지역 변수가 대표적임)이 저장되는 공간
  • 코드 영역과 데이터 영역은 '크기가 고정된 영역'이라는 점에서 정적 할당 영역이라고 부르는 반면, 힙 영역과 스택 영역은 프로세스 실행 과정에서 실시간으로 그 크기가 변할 수 있는 영역이기에 동적 할당 영역이라고도 부름
  • 일반적으로 힙 영역은 메모리의 낮은 주소에서 높은 주소로 할당되고, 스택 영역은 높은 주소에서 낮은 주소로 할당됨(이렇게 해야 힙 영역과 스택 영역에 데이터가 쌓여도 새롭게 할당되는 주소가 겹칠 일이 없음)

 

 

2) 프로세스 상태와 계층 구조

2-1) 프로세스 상태

  • 운영체제는 프로세스의 상태를 PCB를 통해 인식하고 관리함
  • 프로세스가 가질 수 있는 대표적인 상태
    • 생성 상태(new) : 프로세스를 생성 중인 상태(이제 막 메모리에 적재되어 PCB를 할당받은 상태를 의미함)
    • 준비 상태(ready) : 당장이라도 CPU를 할당받아 실행할 수 있지만, 아직 자신의 차례가 아니기에 기다리고 있는 상태
      • 디스패치(dispatch) : 준비 상태인 프로세스가 실행 상태로 전환되는 것
    • 실행 상태(running) : CPU를 할당받아 실행 중인 상태(실행 상태인 프로세스는 할당된 일정 시간 동안만 CPU를 사용할 수 있음)
    • 대기 상태(blocked) : 프로세스는 실행 도중 입출력장치를 사용하는 경우가 있는데 이에 입출력장치의 작업을 기다리는 상태(입출력 작업이 완료되면 해당 프로세스는 다시 준비 상태로 CPU 할당을 기다림)
    • 종료 상태(terminated) : 프로세스가 종료된 상태(프로세스가 종료되면 운영체제는 PCB와 프로세스가 사용한 메모리를 정리함)
  • 프로세스 상태 다이어그램(process state diagram) : 프로세스 상태를 도표로 정리한 것
  • 대기 상태를 좀 더 일반적으로 정리하자면 특정 이벤트가 일어나길 기다릴 때 프로세스는 대기 상태가 되는데 다만 프로세스가 대기 상태가 되는 대부분의 원인이 입출력 작업이기 때문에 '프로세스가 입출력 작업을 하면 대기 상태가 된다'고 생각해도 무방함

 

2-2) 프로세스 계층 구조

  • 프로세스는 실행 도중 시스템 호출을 통해 다른 프로세스를 생성할 수 있는데 이때 새 프로세스를 생성한 프로세스를 부모 프로세스(parent process), 부모 프로세스에 의해 생성된 프로세스를 자식 프로세스(child process)라고 함
  • 부모 프로세스와 자식 프로세스는 엄연히 다른 프로세스이기에 각기 다른 PID를 가짐(일부 운영체제에서는 자식 프로세스의 PCB에 부모 프로세스의 PID인 'PPID;Parent PID'가 기록되기도 함)
  • 부모 프로세스로부터 생성된 자식 프로세스는 실행 과정에서 또 다른 자식 프로세스를 생성할 수 있고, 그 자식 프로세스는 실행 과정에서 또 다른 자식 프로세스를 생성할 수 있음
  • 최초의 프로세스가 자식 프로세스들을 생성하고, 생성된 자식 프로세스들이 새로운 자식 프로세스들을 낳는 형식으로 여러 프로세스가 동시에 실행되는 것인데 이 과정을 도표로 그리면 트리 구조를 띄는데, 이를 프로세스 계층 구조라 함
  • 많은 운영체제는 프로세스가 프로세스를 낳는 프로세스 계층 구조로 프로세스들을 관리함
  • 최초의 프로세스 : 유닉스 운영체제에서는 init, 리눅스 운영체제에서는 systemd, macOS에서는 launchd라고 함
  • 최초의 프로세스 PID는 항상 1번이며, 모든 프로세스 최상단에 있는 부모 프로세스임

 

2-3) 프로세스 생성 기법

  • 부모 프로세스는 fork를 통해 자신의 복사본을 자식 프로세스로 생성해내고, 만들어진 복사본(자식 프로세스)은 exec를 통해 자신의 메모리 공간을 다른 프로그램으로 교체함(fork와 exec는 시스템 호출임)
    • fork : 자기 자신 프로세스의 복사본을 자식 프로세스로 생성하는 시스템 호출
    • exec : 자신의 메모리 공간을 새로운 프로그램으로 덮어쓰는 시스템 호출

 

 

3) 스레드

3-1) 프로세스와 스레드

  • 스레드(thread) : 프로세스 내의 실행 흐름 단위
  • 하나의 프로세스는 여러 개의 스레드를 가질 수 있음
  • 스레드를 이용하면 하나의 프로세스에서 여러 부분을 동시에 실행할 수 있음
  • 스레드라는 개념이 도입되면서 하나의 프로세스가 한 번에 여러 일을 동시에 처리할 수 있게 되었음(즉, 프로세스를 구성하는 여러 명령어를 동시에 실행할 수 있게 됨)
  • 리눅스는 프로세스와 스레드 모두 실행의 문맥(context of execution)이라는 점에서 동등하다고 간주하여 이 둘을 크게 구분짓지 않는데 이에 프로세스와 스레드라는 말 대신 테스크(task)라는 이름으로 통일하여 명명함

 

3-2) 멀티프로세스와 멀티스레드

  • 멀티 프로세스(multiprocess) : 여러 프로세스를 동시에 실행하는 것
  • 멀티 스레드(multithread) : 여러 스레드로 프로세스를 동시에 실행하는 것
  • 스레드끼리는 프로세스 내의 자원을 공유함
  • 프로세스 간 통신(IPC; Inter-Process Communication) : 프로세스끼리는 기본적으로 자원을 공유하지 않지만, 프로세스끼리도 충분히 자원을 공유하고 데이터를 주고받을 수 있는데 프로세스 간의 자원을 공유하고 데이터를 주고받는 것을 말함
  • 공유 메모리(shared memory) : 프로세스들은 서로 공유하는 메모리 영역을 두어 데이터를 주고받을 수 있는데 이때 프로세스들이 공유할 수 있는 메모리 영역을 말함