프로세스(Process), 쓰레드(Thread)
프로세스
- 프로세스 : 실행중인 프로그램
- cf) 프로그램 : 어떤 작업을 위해 실행할 수 있는 파일, 실행중이지 않은 객체.
- 기본적으로 프로세스 마다 최소 1개의 스레드를 갖고 있다 (메인 쓰레드 포함)
- 프로세스 자체가 운영체제 스케줄러에 의해 실행되는 것이 아니라 프로세스 내의 쓰레드가 실행되는 것이다
- 멀티프로세스 : 하나의 컴퓨터에 존재하는 다수의 프로세서에서 다수의 프로그램을 동시에 실행하는 것
- 장점 : 안전성 (메모리 침범 문제를 OS차원에서 해결)
- 단점 : 각 각의 독립된 메모리 영역을 갖고 있어 작업량이 많을수록 오버헤드 발생, 컨텍스트 스위칭으로 인한 성능저하
프로세스 구조
- 각 각의 프로세스는 독립된 메모리 영역(Code, Data, Stack, Heap)을 할당 받는다
- Code(=Text) : 컴파일된 프로그램 코드가 올라가는 영역, Read-Only로 수정이 불가능하다
- Data : 전역변수, 정적변수, 상수, 배열 등의 데이터가 저장되는 영역
- Stack : 함수가 호출되어 지역 변수 등의 임시 데이터가 저장되는 영역 / 동적 할당영역
- Heap : 런타임에 할당할 메모리 영역이 저장되는 영역 (new(), malloc() 등) / 동적 할당영역
프로세스 상태 및 상태전이
상태
- 준비 (Ready)
- 프로세스가 프로세서를 할당받기 위해 기다리고 있는 상태
- 새롭게 생성된 프로세스가 Job Scheduler 에 의해 준비상태가 됨.
- 프로세스는 준비상태큐에서 실행 준비
- 보조기억장치 내에 존재하는 프로그램 실행시 주기억장치로 탑재됨
- 실행 (Run)
- 프로세스가 프로세서를 할당 받아 실행되는 상태
- 준비상태의 프로세스는 CPU Scheduler 에 의해 실행상태가 됨.
- 프로세스 수행 완료 전에 할당 시간이 종료되면 준비상태로 전이
- 입출력 처리가 필요할 경우 대기상태로 전이
- 대기 (Wait, Block)
- 입출력 처리가 필요할 때 현재 실행중인 프로세스가 중단되고 입출력 처리가 완료되는 것을 기다리는 상태
- 입출력이 완료되면 장치 컨트롤러는 CPU에게 인터럽트를 걸고 그 결과 CPU는 OS에게 CPU를 할당시킨다.
- CPU를 할당받은 OS는 해당 프로세스를
Block
->Ready
로 전이시킨다.
- 종료 (Terminated)
- 프로세스 실행이 끝나고 프로세서 할당이 해제된 상태
상태 전이
- 디스패치 (Dispatch) : 준비 → 실행
- 시간 초과 (Time Run-out) : 실행 → 준비
- 깨움 (Wake Up) : 대기 → 준비
Context Switching (컨텍스트 스위칭)
- CPU가 어떤 프로세스를 실행하고 있을 때 인터럽트에 의해 다음 프로세스 실행을 위해 기존 프로세스 정보를 PCB에 저장하고 다음 프로세스의 정보를 PCB에서 가져와 교체하는 작업
- PCB : 프로세스 메타데이터들을 저장해 놓는 곳 / Linked List 방식
- OS가 관리상 필요한 데이터 : 프로세스 상태, 프로세스ID, 스케줄링 정보와 우선순위
- CPU 수행관련 하드웨어 값 : PC, Register
- 메모리 관련 : Code, Data, Stack의 위치정보
- 파일 관련
스케줄러
- 단기 스케줄러 (=CPU Scheduler)
- 어떤 프로세스에게 CPU를 줄지 결정
- Ready -> Run 상태전이를 시킨다
- 매우 빠르게 동작(ms단위)
- 장기 스케줄러 (=Job Scheduler)
- 어떤 프로세스에게 메모리를 줄지 결정
- 새로운 프로세스가 Ready 상태가 된다
- 현대의 Time Sharing System에는 보통 장기 스케줄러가 없고 실행된 프로세스는 바로 Ready상태가 된다
- 중기 스케줄러 (=Swapper)
- 어떤 프로세스에게서 메모리를 뺏을지 결정
- 여유공간을 마련하기 위해 프로세스를 통째로 메모리에서 제거
- 현대는 장기 스케줄러 없이 모든 프로세스가 메모리에 올라가기 때문에 이를 중기 스케줄러가 통제한다.
- 메모리를 빼았긴 상태를
Suspended
라고 한다 - 메모리를 빼았는 전이를
Swap out
, 다시 주는 전이를Swap In
이라고 한다
쓰레드
- 쓰레드 : 프로세스 내의 작업단위
- 프로세스에 할당된 메모리와 CPU 등의 자원을 사용한다
- 실제 CPU에 의해 실행되는 단위는 쓰레드이다 (프로세스가 아님)
-
프로세스와 쓰레드 예시
프로세스 A : 워드 - 쓰레드 1 : 문서 편집 - 쓰레드 2 : 자동 저장 - 쓰레드 3 : 맞춤법 검사 프로세스 B : 유튜브 - 쓰레드 1 : 영상 재생 - 쓰레드 2 : 댓글
- 멀티쓰레드 : 하나의 프로세서에서 다수의 쓰레드를 돌리는 것
- 스레드들이 공유 메모리를 통해 다수의 작업을 동시에 처리하도록 도와줌
- 장점 : 독립된 프로세스에 비해 공유 메모리만큼의 시간&자원 손실이 감소, 전역&정적 변수에 대한 자원 공유 가능, 컨텍스트 스위칭시 캐시 메모리를 비울 필요가 없어 비용이 적고 더 빠르다
- 단점 : 하나의 쓰레드가 공유 메모리를 망가뜨리면 모든 쓰레드가 작동 불능상태가 됨. → Critical Section 으로 대비
- 동시성 : 하나의 CPU가 여러 쓰레드를 번갈아가면서 실행해 동시에 처리 하는 것
- 병렬성 : 여러 개의 CPU가 여러 쓰레드를 실행해 병렬로 처리하는 것
- 병렬성은 동시성에 포함되어 있는 개념
쓰레드 구조
- 쓰레드는 프로세스 내에서 각 각의 Stack만 따로 할당 받고 Code, Data, Heap은 공유한다
- 각 각의 쓰레드는 프로세스 내의 하나의 Heap을 공유하여 실행이 가능하다
- 한 쓰레드가 프로세스 자원을 변경하면 다른 쓰레드에서 그 결과를 즉시 확인할 수 있다
쓰레드의 적정한 개수
- CPU 바운드 작업 : CPU의 연산 능력을 많이 요구하는 작업
- ex) 복잡한 수학 연산, 데이터 분석, 비디오 인코딩, 과학적 시뮬레이션 등
- I/O 바운드 작업 : 디스크, 네트워크, 파일 시스템 등과 같은 입출력(I/O) 작업을 많이 요구하는 작업
- ex) 데이터베이스 쿼리 처리, 파일 읽기/쓰기, 네트워크 통신, 사용자 입력 처리 등
- 웹 애플리케이션 서버
- 일반적으로 CPU 바운드 작업 보다는 I/O 바운드 작업이 더 많음
- 사용자의 요청 하나를 처리하는데 CPU를 1%만 사용한다면 단순하게 생각해도 100개의 스레드를 만들 수 있다
-
CPU-바운드 작업: CPU 코어 수 + 1개
- CPU를 거의 100% 사용하는 작업이므로 스레드를 CPU 숫자에 최적화
-
I/O-바운드 작업: CPU 코어 수 보다 많은 스레드를 생성, CPU를 최대한 사용할 수 있는 숫자까지 스레드 생성
- CPU를 많이 사용하지 않으므로 성능 테스트를 통해 CPU를 최대한 활용하는 숫자까지 스레드 생성
- 단 너무 많은 스레드를 생성하면 컨텍스트 스위칭 비용도 함께 증가허기에 적절한 성능 테스트 필요