본문 바로가기
프로그래밍/리눅스

리눅스(Linux) 프로세스의 작동

by bantomak 2025. 1. 31.
반응형

프로세스의 생애 주기(Process Life cycle)

프로세스를 운영체제 안에서 살아가는 생물이라고 보면 이해라기 쉽다. 우리가 지구라는 환경에서 살아가듯 프로세스는 운영체제라는 세계 안에 존재한다. 어떤 종의 개체가 태어나고 죽듯이 프로그램이 실행되면 프로세스가 생성되고 소멸된다.

  • 현실 세계 : 컴퓨터 시스템
  • 지구 : 운영체제
  • 생물의 종류 : 프로그램의 종류
  • 생명의 탄생 : 프로세스의 생성
  • 생명의 죽음 : 프로세스의 소멸

사용자가 계산기 프로그램을 켭니다. 프로그램이 실행되며 프로세스가 생성된다. 이 프로세스는 계산기 프로그램을 실행하는데 필요한 여러 정보를 관리하는 객체이다. CPU가 프로그램을 실행하려면 프로그램의 실행 코드가 메모리에 적재되어야 한다. 그리고 메모리에 적재된 코드 정보는 프로세스에 저장하고 관리한다. 코드뿐만 아니라 실제 프로그램이 작동하는 데 필요한 정보도 메모리에 저장한다. 그리고 정보를 저장한 위치는 프로세스에서 관리한다.

 

사용자가 프로그램을 닫으면 프로그램은 종료된다. 프로그램이 실행되며 프로세스가 생성되는 것처럼 프로그램이 종료되면 프로세스도 종료된다. 프로세스가 종료될 때는 프로세스가 생성될 때와 반대로 동작한다. 메모리 영역을 포함해 프로세스가 관리하던 자원을 모두 해제한다. 해제된 자원은 다시 운영체제가 관리하는 미사용 자원에 포함된다. 이렇게 해야 다음에 실행될 프로그램이 문제없이 작동할 수 있다.

멀티 태스킹을 위한 여러 기법

윈도우나 리눅스 같은 운영체제는 여러 프로그램을 동시에 실행할 수 있게 설계돼 있다. 한 번에 여러 일을 동시에 처리하는 것을 멀티 태스킹(multi-tasking)이라고 한다. 멀티 태스킹은 운영체제의 역할 중 하나이며, 운영체제가 멀티 태스킹을 지원하는 데 필요한 기능과 기법을 알아보자.

프로세스 스케쥴링(Process Scheduling)

프로그램의 실행 코드를 실제로 실행하는 주체는 CPU이다. CPU는 한 순간에 한 가지 작업만을 할 수 있다. 그래서 여러 프로그램을 동시에 실행한다는 말은 정확한 표현이 아니다. 하지만 윈도우만 보더라도 분명히 여러 프로그램을 동시에 사용할 수 있다 사실 이것은 운영체제가 여러 프로그램을 동시에 실행하는 것처럼 보이도록 여러 프로세스를 아주 빠르게 번갈아 가며 실행하기 때문이다. 그저 속도가 너무 빨라서 사람은 이를 눈치채지 못하는 것이다.

 

여러 프로세스 중에 CPU가 처리할 프로세스를 결정하는 행위를 프로세스 스케줄링(process scheduling)이라고 한다. 그리고 이를 담당하는 주체는 프로세스 스케줄러라고 한다. 프로세스 스케줄링은 운영체제에서 작동하는 모든 프로세스에 적용돼야 한다. 그래서 프로세스 스케줄러는 커널 영역에서 작동한다.

스케줄링 알고리즘(Scheduling Algorithm)

프로세스 스케줄러는 여러 프로그램이 동시에 문제없이 처리되도록 CPU가 처리할 프로세스를 잘 선택해야 한다. 운영체제에는 다양한 종류의 프로세스가 있고, 프로세스마다 그 특성이 다르다. 상황에 따라 급하게 처리해야 할 프로세스가 있고, 느긋하게 처리해도 되는 프로세스도 있다. 프로세스가 CPU를 점유하는 시간도 고려해야 한다. 프로세스 스케줄러가 처리할 프로세스를 선택하는 방법을 스케줄링 알고리즘(scheduling algorithm)이라고 한다. 스케줄링 알고리즘이 가져야할 속성은 다음과 같다.

  • 공평성 : 모든 프로세스가 공평하게 처리되어야 한다. 어떤 프로그램은 잘 동작하고 어떤 프로그램은 작동하지 않는 상황이 일어나서는 안된다.
  • 우선순위 : 어떤 프로세스는 우선순위가 높고, 다른 프로세스는 상대적으로 우선순위가 낮을 수 있다. 설정된 우선순위에 따라 스케줄링이 가능해야 한다.
  • 효율성 : 시스템 자원을 효율적으로 사용해야 CPU가 처리할 수 있는 양이 많아진다. 스케줄링 알고리즘에서도 시스템 자원을 효율적으로 사용할 수 있는 방법을 제공해야 한다.
  • 응답 시간 : 사용자나 프로세스가 요청한 동작에 대한 응답 시간을 최소화해야 한다.

하지만 스케줄링 알고리즘은 운영체제의 목적에 따라 중요한 속성이 다르다. PC에서는 일반 프로그램이 주로 작동하니 여러 프로그램이 두루두루 잘 실행되는 것이 좋다. 하지만 특수 장비에 탑재되는 운영체제는 우선순위가 높은 프로그램이 정해진 시간 안에 실행을 완료하는 것이 훨씬 중요할 수도 있다.

컨텍스트 스위칭(Context Switching)

프로세스 스케줄러는 여러 프로세스 중 하나를 선택해 CPU에 처리를 맡긴다. 그리고 어느 정도 시간이 흐른 후 프로세스 스케줄러가 실행할 프로세스를 변경한다. 이때 CPU가 처리하던 프로세스는 실행이 끝나지 않은 상태로 중단된다. 언젠가 중단된 프로세스가 다시 CPU에서 처리할 차례가 되면 중단된 상태를 그대로 복원하고 실행을 재개해야 매끄럽게 처리된다. 이처럼 프로세스 스케줄링에 따라 처리되는 프로세스가 변경되는 일련의 과정을 컨텍스트 스위칭(context switching, 문맥 교환)이라고 한다. 

  • 현재 프로세스의 상태 저장 : 실행 중인 프로세스가 다른 프로세스로 변경되려 할 때, 현재 프로세스가 처리 중이던 내용을 모두 저장해야 한다. 그래야 다음에 다시 스케줄링됐을 때 이어서 처리할 수 있기 때문이다. 프로그램 카운터 레지스터, 스택 포인터 레지스터 등 레지스터 값과, 프로세스 상태 정보, 메모리 상태 정보 등을 커널의 프로세스 제어 블록(PCB, Process Control Block)이라는 곳에 저장한다. (컨텍스트 스위칭이 일어나면 CPU의 레지스터 값들이 모두 PCB에 저장된다.)
  • 다음 프로세스 선택과 실행 : 다음에 실행할 프로세스가 결정되면 실행할 프로세스의 PCB에 저장된 상태 정보를 CPU의 레지스터에 복원한다. 이 작업이 완료되면 CPU는 새로운 프로세스를 처리한다.

시스템 효율성이 올라가려면 컨텍스트 스윙치 오버헤드가 작도록 구현해야 한다. 컨텍스트 스위칭이 너무 자주 발생하면 프로그램 응답성은 좋다. 하지만 컨텍스트 스위칭 오버헤드가 너무 커져 시스템 효율성이 떨어지게 된다. 반대로 컨텍스트 스위칭이 너무 뜸하면 효율성은 높아지지만 응답성이 떨어지게 된다.

컨텍스트 스위칭을 발생시키는 이벤트

다음과 같은 이벤트가 발생하면 컨텍스트 스위칭이 일어난다.

  • 인터럽트(interrupt) : 하드웨어로부터 발생하는 이벤트로, 이를 처리하기 위해 실행 중인 프로세스를 중단한다.
  • 시스템 콜(system call) : 프로세스가 파일 읽기/쓰기, 네트워크 통신 요청 등 운영체제의 기능을 요청할 때 시스템 콜을 호출한다. 프로세스가 시스템 콜을 호출하면 다른 프로세스가 CPU를 점유할 수 있도록 컨텍스트 스위칭이 일어난다.
  • 시그널(signal) : 프로세스가 수신하는 시그널에 따라 프로세스의 동작이 중단될 수 있다. 예를 들어, 프로세스가 SIGSTOP 시그널을 받으면 프로세스 상태를 저장하고 컨텍스트 스위칭이 일어난다.
  • 예외(exception) : 프로세스 실행중 예외가 발생하면 해당 예외를 처리하는 동안 다른 프로세스로의 컨텍스트 스위칭이 일어난다.

프로세스 상태(Process Status)

프로세스 상태(process status)는 다음과 같이 분류할 수 있다.

  • 실행/실행 대기 상태(running/runnable) : 프로세스가 CPU에 의해 처리중이거나 처리되기를 기다리는(실행 대기) 상태이다.
  • 중단 상태(stopped) : 프로세스 중단 시그널(SIGSTOP)을 받아 프로세스가 멈춘 상태이다. 이 상태에서 프로세스 재시작 시그널(SIGCONT)을 받으면 다시 실행 상태가 될 수 있다.
  • 종료 상태(terminated) : 프로세스가 exit() 함수 등에 의해 종료된 상태이다. 프로세스가 종료된 후 해당 프로세스의 부모 프로세스가 종료 처리를 해줘야 정상 종료된다. 그렇지 않으면 좀비 프로세스가 된다.
  • 수면 상태(sleep) : 프로세스가 오랜 기간 어떤 이벤트를 기다리는 상태이다. 디스크와같은 외부 장치에 대해 읽기/쓰기 요청을 하면 응답이 오기까지 긴 시간이 필요하다. 이런 프로세스가 실행 또는 실행 대기 상태로 응답을 기다리면 다른 프로세스는 CPU를 사용할 수 없으니 민폐가 된다. 그래서 수면 상태로 이벤트를 기다린다. 수면 상태도 인터럽트(interrupt)에 의해 깨어날 수 있는 (interruptible sleep) 수면 상태와 인터럽트에 의해 깨어나지 않는(uninterruptible sleep) 수면상태로 나눌 수 있다. 깨어나지 않는 수면 상태는 디스크 I/O와 같은 기다리던 이벤트가 발생해야 깨어날 수 있다.

프로세스 종료 상태

프로세스는 종료될 때 프로세스 종료 상태를 남긴다. 프로세스 종료 상태(process exit status)는 프로세스가 어떻게 종료됐는지를 나타내는 상태 정보이다. 프로세스 종료 상태는 0~255 사이 정수인 종료 코드와 프로세스가 종료될 때 받은 시그널 정보로 구성되어 있다. 종료 코드(리턴 코드라고 함)는 프로세스가 종료되면서 명시적으로 남기는 값이다. 일반적으로 종료 코드에서 0은 성공, 9 이외의 값은 실패를 의미한다. 프로세스가 받은 시그널 정보는 프로세스가 비정상 종료되는 경우를 위한 정보이다. 프로세스가 시그널을 받아 종료됐는지, 그렇다면 시그널 종류는 무엇인지를 정하고 있다.

프로세스의 관리 정보

프로세스 관리는 운영체제의 핵심 역할 중 하나이다. 운영체제는 각 프로세스의 정보를 PCB에 모아 관리한다. PCB에서 관리하는 정보는 다음과 같다.

  • PID(Process ID) : 프로세스 고유의 ID로, 다른 프로세스와 중복되지 않는다. 정수형 데이터이다.
  • PPID(Parent Process ID) : 부모 프로세스의 PID를 저장한다.
  • 프로세스 상태 정보 : 실행, 중단, 수명 등 프로세스 상태 정보를 저장한다.
  • 프로세스 우선순위 및 스케줄링 정보 : 프로세스의 우선 순위와 스케줄링에 관한 정보를 저장한다.
  • 레지스터 값 : CPU 레지스터에서 사용하던 값을 저장한다.
  • 메모리 정보 : 코드, 데이터, 스택 영역 등의 위치와 크기를 저장한다.
  • 파일 디스크립터 정보 : 열린 파일의 파일 디스크립터 정보를 저장한다.
  • 시그널 처리 정보 : 시그널을 처리하기 위한 시그널 핸들러와 시그널 마스크 등을 저장한다.
  • 자원 사용량 및 제한 정보 : CPU 시간, 메모리 사용량 등 자원 사용 정보를 저장한다.

스레드(Thread)

프로세스와 프로세스 스케줄러를 적용함으로써 운영체제는 멀티 태스킹을 지원할 수 있었다. 하지만 프로세스의 동작 방식에서 여러 아쉬운 점이 드러났다. 프로세스 간에 데이터를 교환하거나 공유하려면 IPC(Inter-Process Communication, 프로세스 간 통신 도구)를 이용해야 한다. 그런데 IPC를 이용한 데이터 교환과 공유는 성능에 병목현상을 일으킨다. 또한, 컨텍스트 스위칭으로 인한 오버헤드가 커서 시스템 효율이 낮다.

 

이런 문제를 해결하기 위해서 스레드라는 개념이 도입되었다. 스레드는 프로세스의 가장 작은 실행 단위이다. 한 프로세스에는 여러 스레드가 존재할 수 있다. 프로세스 내에 스레드가 1개 존재하면 싱글 스레드 프로세스(single-threaded process), 여러개 존재하면 멀티 스레드 프로세스(multi-threaded process)라고 한다.

멀티 스레드 프로세스에서 각 스레드는 프로세스 내 다른 스레드와 메모리 공간을 공유하면서 독립된 스택 영역과 실행 컨텍스트(스케줄링 된 스레드가 하던 일을 계속하기 위한 정보 또는 상황)를 유지할 수 있다. 즉, 일부 메모리 영역은 스레드 간에 공유하면서 실행 코드는 스레드별로 실행되는 구조이다. 또한 스레드는 프로세스보다 훨씬 적은 비용으로 생성 및 종료가 가능하다.

함께 읽으면 좋은 글

 

프로세스 제어 블록 (PCB, Process Control Block)란?

프로세스 제어 블록(PCB)이란? 운영체제가 프로세스를 제어하기 위해 정보를 저장해 놓은 곳으로, 프로세스의 상태 정보를 저장하는 구조체이다. 프로세스 상태 관리와 문맥교환(Context Switching)을

jettstream.tistory.com

 

C# 스레드(Thread)에 대해서

스레드(Thread)란 무엇인가프로세스(Process)와 스레드(Thread)의 차이프로세스와 스레드는 컴퓨터에서 동작하는 작업의 단위입니다.각각의 작업은 독립적으로 실행되며, 다른 작업에 영향을 미치지

jettstream.tistory.com

 

Linux Process States and Signals

When troubleshooting a system, it's important to understand the process life-cycle and how the scheduler divides the CPU cores between the…

cloudchef.medium.com

댓글