[운영체제] 프로세스 관리 - 프로세스와 쓰레드
우리가 컴퓨터를 사용할때 브라우저, 카카오톡 등 여러가지 응용 프로그램을 사용한다. 각 프로그램들은 실행되기 위해서 메모리 공간과 자원을 할당받아야하고 실행된 후에도 지속적으로 관리되어야 하는데 이와 같은 과정을 운영체제가 처리해준다. 즉, 운영체제는 메모리와 CPU를 사용하여 프로그램 실행을 돕고 관리해준다.
프로세스와 쓰레드는 운영체제에서 프로세스 관리를 위한 기본적인 개념이다. 이를 이해하면 프로그래밍 언어의 동작 원리를 이해하기 쉽고 멀티 쓰레딩, 병렬처리 등 컴퓨팅 기술의 핵심 개념을 이해힐 수 있다. 따라서 프로세스와 쓰레드는 개발자가 알야아하는 기본적인 개념들이다. 이번 포스팅에서 두 개념과 동작원리를 자세히 살펴보자.
프로세스
프로세스란 디스크에 저장된 프로그램을 실행한 상태를 의미한다. 이때 프로그램은 메모리에 올라가며 메모리에 자신만의 공간을 배정받으며 CPU의 자원을 할당받게 된다. 프로세스는 아래와 같은 특징을 가지고 있다.
특징
- 본인의 상태저장공간인 PCB를 가지고 있음
- 본인의 독립적인 메모리 공간을 가짐
- 프로세스간 서로 영향을 주지 않음
프로세스의 동작과정
- new(생성)
- 프로그램이 메모리에 올라와 프로세스가 생성되는 상태
PCB
(프로세스 상태저장공간) 생성
- ready(준비)
- CPU 자원을 할당 받기위해 기다리는 상태
CPU 스케줄링
에 의해 ready 상태에서 running 상태로 넘어간다.
(CPU 스케줄링에 관한 내용은 다음 포스트에서 알아보자)
- running(실행)
- CPU 자원을 할당받아 실행중인 상태
Context Switching
이 일어나면 ready 상태로 돌아감Context Switching
은 timeout 혹은 interrupt가 발생시 일어난다.
(이 개념에 대한 내용은 아래에서 자세하게 살펴보자)
- terminated(완료)
- 프로세스의 실행이 완료된 상태
PCB
가 삭제됨
- wait(대기)
- running 상태의 프로세스가 I/O 처리해야하는 경우
- 처리 완료시 ready 상태가 되고 running 상태가 될때까지 기다림
🤔 프로세스가 상태교환을 반복하는 이유
CPU는 하나의 프로세스만을 처리하는 것이 아니라 다수의 프로세스를 처리한다. CPU는 일반적으로 한 번에 하나의 일만 처리할 수 있으므로 다수의 프로세스를 처리하기 위해 상태를 바꿔가며 처리한다. 이때 ready -> running 상태로 바꾸는 규칙을 CPU 스케줄링이라고 부르며 여러가지 메커니즘이 존재한다.
프로세스 제어공간과 문맥교환(PCB, Context Switching)
앞서 동작과정에서 살펴보았든 프로세스의 상태는 계속 바뀌게 된다. 실행 프로세스가 바뀔때 프로세스가 어느 부분에서부터 어떻게 처리해야 하는지를 저장해야 이후 재실행시 효율적으로 실행할 수 있다. 따라서 현재까지 진행상황, 프로세스를 식별할 ID 등의 상태를 저장할 필요가 있다. 이러한 상태저장 공간을 PCB(Process Control Block)라고 부르며 메모리의 OS영역에 생성된다.
PCB에는 현재상태(다음 명령어 주소, 사용하던 register 값)뿐 아니라 CPU 스케줄링에서 중요하게 사용되는 프로세스 우선순위 정보, 조금 뒤 설명할 부모/자식 프로세스의 ID 등도 들어가있다.
PCB는 프로세스의 Context Switching(문맥교환)
이 일어날때 읽고 쓰인다. 문맥교환은 Timeout 혹은 interrupt가 발생시 실행 프로세스를 바꾸는 과정이다. PCB에 저장된 프로세스들의 정보를 꺼내 CPU register를 재설정한다.
💡 interrupt
interrupt(인터럽트)는 프로세스 실행 중 예외상황이 발생하여 처리가 필요한 경우 CPU에게 알려 처리하는 것을 말한다. 인터럽트는 하드웨어 인터럽트와 소프트웨어 인터럽트로 나뉜다.
👉 하드웨어 인터럽트 - 입출력 I/O, 0으로 나누기
👉 소프트웨 인터럽트 - 시스템콜, 프로그램 처리 중 명령
프로세스의 메모리 공간
프로세스가 생성될 때 메모리에는 크게 2가지 공간을 할당한다. 이때 사용자영역에 제공되는 메모리공간은 다시 4가지 구조로 나누어진다.
- 메모리의 OS 영역에 PCB 할당
- 메모리의 사용자 영역에 관련된 메모리공간이 할당된다.
- Code
- 디스크에서 읽어온 프로그램이 저장됨
- 우리가 작성한 코드들이 여기에 저장된다.
- Data
- global(전역)변수와 static(정적)변수들이 저장된다.
- 프로세스 종료까지 할당해제되지 않는다.
- Stack
- local(지역)변수들이 저장된다
- Heap
- 동적으로 메모리를 할당할때 사용된다.
프로세스 복사와 좀비 프로세스
프로세스 실행 중 프로세스를 복사할 수 있다.(fork
) 이때 실행중인 프로세스가 부모 프로세스가 되고 복사된 프로세스가 자식 프로세스가 된다. 자식 프로세스와 부모 프로세스간 프로세스 전환(exec
) 시에 PCB는 변경되지 않고 메모리 공간만 교체된다.
자식 프로세스의 실행이 끝나면 부모 프로세스가 자원을 회수한다. 이때 자식 프로세스가 비정상적으로 종료되었거나 부모 프로세스가 먼저 종료된다면 자식 프로세스의 자원이 사라지지 않고 남는 좀비/고아 프로세스가 된다. 이러한 프로세스들은 명령어를 통해 직접적으로 종료해야한다.
쓰레드
프로세스 내에서 실행되는 작은 실행 단위이다. 프로세스에서 실질적인 작업 실행은 쓰레드의 역할이다. 즉, 각 프로세스마다 적어도 하나의 쓰레드가 동작한다.
특징
- 하나의 프로세스에서 다수의 쓰레드가 실행될 수 있음
- 프로세스의 메모리를 공유함(Code, Data, Heap)
- 쓰레드만의 메모리 공간을 가짐(Stack)
쓰레드 주소 공간 - TCB
프로세스내에서도 다수의 쓰레드가 실행될 수 있으므로 쓰레드간의 Context Switching
이 일어난다. 따라서 쓰레드의 상태저장공간(TCB) 또한 별도로 필요하다. TCB(Thread Control Block)은 PCB 내부에 저장되어 있으며 마찬가지로 식별ID, 다음 명령어 주소 등을 가지고 있다.
멀티 쓰레딩
하나의 프로세스 내에서 다수의 쓰레드를 사용하여 처리하는 방법을 멀티쓰레딩이라고 부른다. 멀티쓰레딩은 여러 작업을 동시에 처리하여 성능 향상시킨다는 장점이 있지만 공유 메모리에 동시접근함으로써 발생하는 동시성문제 또한 가지고 있다.
장점
- 각 쓰레드가 자원공유를 하기 때문에 적은 메모리를 사용한다.
- 각 실행흐름이 독립적이라 쓰레드 작업종료를 기다리지 않고 비동기 처리가 가능하다.
- 공유하는 내용이 있으므로 컨텍스트 스위칭 비용이 감소한다.
단점
- 공유 메모리에 동시 접근시 문제가 발생한다. 이를 처리하기 위한 작업이 필요한다
- 여러 쓰레드가 동시 동작하기때문에 동작파악, 디버깅이 어려워질 수 있다.
💡 멀티 프로세스
프로세스 또한 다수의 프로세스를 이용하여 작업을 처리할 수 있다. 하지만 프로세스는 별도의 메모리공간을 가지므로 데이터를 주고받기 위해 IPC 기법을 활용해야한다. 멀티 프로세스는 안정성이 높으나 멀티쓰레드에 비해 Context Switching
의 비용이 커 상대적으로 느릴 수도 있다. 따라서 안정성이 중요하거나 메모리를 많이 사용하는 상황에 사용하기 좋다.
🤔 Stack 영역과 실행흐름의 연관관계
지역변수, 함수의 파라미터 등이 속하는 Stack 영역이 독립적이라는 것은 곧 독립적인 함수 호출이 가능하다는 뜻이다. 이는 다른 쓰레드가 사용하는 메모리와의 연관관계가 없다는 것을 의미하므로 독립적으로 실행이 가능하다는 것을 의미한다.
쓰레드를 이용한 프로그래밍의 장점
- 자원공유의 이점
같은 메모리 공간을 공유하므로 쓰레드간 자원 공유가 빠르고 효율적으로 이루어진다. - 빠른 실행(빠른 컨텍스트 스위칭)
문맥교환시, 프로세스 간 전환보다 훨씬 빠르다. - 병렬 처리
멀티코어 프로세서에서의 동시 실행이 가능하다. - 경제성
프로세스 내부에 생성되기 때문에 프로세스 생성에 따른 메모리 및 자원 사용량이 적다.
댓글남기기