1. 프로세스(Process)
1-1. 프로그램(Program)
- 어떤 문제를 해결하기 위하여 그 처리 방법과 순서를 기술하여 컴퓨터에 주어지는 일련의 명령문 집합체
- 사용자의 입력에 따라 그 입력된 값을 일정한 처리 방법과 순서에 따라 처리하여 결과를 산출해내는 명령문 집합
- 디스크 내 파일로 존재 → 동작을 하지 않는 정적·수동적 개체
1-2. 정의
- 실행 중인 프로그램
- 운영체제로부터 자원을 할당 받아 동작
- 동작을 하는 능동적인 개체
1-3. 문맥교환(Context Switch)
1-3-1. 문맥(Context)
- CPU가 프로세스를 실행하면서 필요한 내용
- 프로세스 중단 시에 보존되고 다시 복구되어야하는 프로세스의 모든 실행 정보
1-3-2. 정의
하나의 프로세스가 CPU를 사용 중인 상태에서 다른 프로세스가 CPU를 사용하도록 하기 위해 이전의 프로세스 상태(문맥)를 보관하고 새로운 프로세스의 상태를 적재하는 작업
1-3-3. 발생 시점
✅ 인터럽트 처리(Interrupt Handling)
- 인터럽트 발생 → Context Switching
✅ 멀티태스킹(Multi-Tasking)
- 실행 가능한 프로세스들이 운영체제의 스케줄러에 의해 번갈아가며 수행되는 것
- 각 프로세스는 번갈아가며 CPU를 할당 받음 → Context Switching
- Context Switching 시 속도가 매우 빠르므로 동시에 처리되는 것처럼 느낌
✅ 사용자 모드 - 커널 모드 간 전환
1-3-4. 과정
1. 운영체제에 의해 Interrupt나 System call이 발생함
2. 운영체제가 현재 실행중인 프로세스(P0)의 상태 정보를 PCB0에 저장
3. 운영체제가 다음에 실행할 프로세스(P1)의 상태 정보를 PCB1으로부터 복구하여 CPU를 할당
4. 또 다시 Interrupt나 System call이 발생하는 경우 2~3을 반복
1-4. 메모리 구조
- 프로그램 실행에 직접적으로 필요한 코드와 데이터로 구성
1-5. 프로세스 제어 블록(Process Control Block: PCB)
1-5-1. 정의
- 운영체제가 프로세스를 관리하기 위해 필요한 정보를 보관하는 운영체제 커널의 자료 구조
- 각 프로세스마다 존재
- 여러 프로세스가 번갈아 실행될 때 PCB에 저장된 정보 활용
1-5-2. 포함 정보
1-6. 상태 관리
1-6-1. 상태
상태 | 설명 |
---|
생성 (create) | 처음 작업이 시스템에 주어진 상태 |
준비 (ready) | 실행 준비가 되어 CPU 할당을 기다리는 상태 |
실행 (running) | 프로세스가 처리되는 상태 |
대기 (wating) | 프로세스가 I/O 작업이 끝날 때까지 또는 특정 자원을 할당받을 때까지 보류되는 상태 |
종료 (terminated) | 프로세스가 더 이상 실행되지 않도록 끝난 상태 |
1-6-2. 상태전이
항목 | 상태변화 | 설명 | 비고 |
---|
| 생성 → 준비 | PCB와 메모리 구조가 생성되었을 때 | |
디스패치 (dispatch) | 준비 → 실행 | 프로세스가 CPU를 할당받았을 때 | |
보류 (block) | 실행 → 대기 | I/O 작업 또는 페이지 교환 요구가 발생한 경우 | CPU 자진 반납 |
깨움 (wakeup) | 대기 → 준비 | 재개 조건(I/O 작업 또는 자원할당 완료)을 만족하는 경우 | |
시간제한 (timeout) | 실행 → 준비 | 스케줄러가 다른 스로세스를 선택한 경우 | CPU 강제 회수 |
- | 실행 → 종료 | 모든 처리가 완료되거나 운영체제가 프로세스를 강제로 종료시키는 경우 | |
- | 종료 | 프로세스에 할당되었던 자원 회수 | |
1-7. 멀티 프로세스(Multiprocessing)
1-7-1. 정의
2개 이상의 CPU가 존재하여 여러 프로세스를 동시에 실행 할 수 있는 시스템
1-7-2. 특징
- 각 프로세스는 독립적으로 실행(개별적으로 메모리 차지)
- 동기화 작업이 필요하지 않음
- 자원 소모적 : 시스템 자원을 많이 사용하거나 낭비하게 됨
- CPU 처리할 항목이 없는 경우 유휴 상태 유지
→ 문제 발생 시 사용하지 않는 CPU가 백업 역할 수행 가능(시스템 안정성 향상)
- IPC를 사용하여 통신
- Context Switching 비용이 큼
- CPU가 다음 프로세스의 정보를 불러오기 위해 메모리 검색, CPU 캐시 메모리 초기화, 프로세스 상태 저장, 데이터 적재를 해야하기 때문
1-7-3. 종류
✅ 대칭 멀티프로세스
- 하나의 메모리 공간으로 연결된 두 개 이상의 동일한 프로세서를 통합하는 컴퓨터 하드웨어 및 소프트웨어 사용
- 모든 I/O 장치에 대한 완전한 접근 권한을 가지며 동등한 대우를 받음
✅ 비대칭 멀티프로세스
- 서로 다른 CPU가 별도의 I/O 장치에 액세스 가능
- EX) 한 CPU는 I/O 작업 수행, 다른 CPU는 운영체제 유지 관리에 집중
1-8. 병행 프로세스(Concurrent Process)
1-8-1. 정의
- 병행성(concurrency) : 여러 개의 프로세스 또는 쓰레드가 동시 수행되는 시스템의 특성
- 동시 수행되는 여러 개의 프로세스 또는 쓰레드
1-8-2. 프로세스 간 관계
| 독립 프로세스(Independent Process) | 협력 프로세스(Cooperating Process) |
---|
영향 여부 | 수행 중인 다른 프로세스에 영향을 주고받지 않음 | 수행 중인 다른 프로세스에 영향을 주고받음 |
데이터 및 상태 공유 | X | O |
실행결과 결정요소 | 입력(결정적) | 실행순서(비결정적) |
실행결과 재생가능 여부 | 같은 입력에 대해 항상 동일한 실행결과 | 같은 입력에 대해 항상 동일한 실행결과 보장 X |
1-8-3. 프로세스 간 통신(IPC: Interprocess Communication)
1-8-3-1. 정의
프로세스들 사이에 서로 데이터를 주고받는 행위 또는 그에 대한 방법이나 경로
1-8-3-2. 방법
1-8-3-2-1. 메시지 전달(Message Passing)
✅ 정의
- 서로 다른 프로세스가 서로 메시지를 주고받으며 실행되는 것
- 커널을 통해 메시지 전달
- 직접 메시지를 전달하는 방법이 존재하지 않음
- 프로세스 사이에 공유 변수를 일체 사용하지 않고 통신함(Message System)
✅ 방법
- Direct Communication : 통신하려는 프로세스의 이름을 명시적으로 표시
- Indirect Communication : mailbox(또는 port)를 통해 메시지를 간접 전달
1-8-3-2-2. 주소 공간 공유(Shared Memory)
- 프로세스 협력을 위해 서로 다른 프로세스 간에도 일부 주소 공간을 공유
- 프로세스 생성 시 기본적으로 주소 공간이 겹치지 않음 → 커널에게 system call 요청 필요
- 스레드 간 협력 ≠ 프로세스 간 협력
- 동일한 process를 구성하는 thread들간에 주소 공간을 공유하므로 협력 가능
1-9. 프로세스 생성
1-9-1. 프로세스 생성 방법
- 사용자가 프로그램을 직접 실행
- 한 프로세스가 다른 프로세스 생성 → 프로세스 생성 시스템 호출 이용
- 부모 프로세스(parent process) : 시스템 호출을 하는 프로세스
- 자식 프로세스(child process) : 시스템 호출을 통해 새로 생성된 프로세스
1-9-2. 프로세스 생성 시스템 호출
1-9-2-1. UNIX, Linux
fork()
: 자식 프로세스가 부모 프로세스의 복제본으로 생성
exec()
: 자식 프로세스가 부모 프로세스와 다른 프로그램 실행
1-9-2-2. Windows
CreateProcess()
: 자식 프로세스가 부모 프로세스의 복제가 아닌 새로운 프로그램으로 생성
2. 스레드(Thread)
2-1. 정의
- 프로세스 내에서의 다중처리를 위해 제안된 개념
- 하나의 프로그램을 실행하기 위한 기본적인 단위
- 디스패칭의 단위
- 하나의 프로세스 내에는 하나 이상의 쓰레드가 존재함
2-2. 메모리 공간
Register
, Stack
→ 스레드 별 소유
Code
, Data
, Heap
→ 공유
- 한 스레드가 프로세스 자원 변경 시 다른 이웃 스레드(sibling thread)도 변경됨
2-3. 스레드 제어블록(Thread Control Block: TCB)
2-3-1. 정의
- 스레드를 관리하는 데 필요한 스레드 별 정보가 포함된 운영체제 커널의 데이터 구조
- 각 스레드마다 존재
2-3-2. 포함 정보
2-4. 사용자 수준 스레드와 커널 수준 스레드
2-4-1. 커널 수준 스레드(Kernel-level Thread)
2-4-1-1. 정의
- 가장 가벼운 커널 스케줄링 단위
- N개의 커널 스레드가 N개의 사용자 스레드 담당(1:1)
→ 병렬성 ↑, 효율성 ↓
- 커널 영역에서 스레드 연산 수행
- 커널이 스레드 관리 → 커널에 종속적
- 프로그래머 요청에 따라 스레드를 생성하고 스케줄링 하는 주체가 커널인 경우
2-4-1-2. 장점
- 프로세스의 스레드들을 몇몇 프로세서에 한꺼번에 디스패치 가능
→ 멀티프로세서 환경에서 매우 빠르게 동작
- 다른 스레드가 I/O 작업을 종료할 때까지 다른 스레드를 사용하여 다른 작업 진행 가능
- 커널이 각 스레드를 개별적으로 관리
- 커널이 직접 스레드를 제공 → 안정성 및 다양한 기능 제공
2-4-1-3. 단점
- 스케줄링 및 동기화 필요
- 커널 호출 시 무겁고 오래걸림(저장한 내용 다시 불러와야 함)
- 사용자 모드에서 커널 모드로 빈번한 전환 발생 → 성능 저하 발생
- 사용자가 프로그래밍할 때 구현하기 어렵고 자원을 더 많이 소비
2-4-2. 사용자 수준 스레드(User-level Thread)
2-4-2-1. 정의
- 사용자 영역에서 스레드 연산 수행
- 커널에 의존적이지 않음
- 스레드의 기능을 제공하는 라이브러리를 활용하는 방식
- 1개의 커널 스레드가 N개의 사용자 스레드 담당(1:N)
2-4-2-2. 장점
- 운영체제에서 스레드를 지원할 필요가 없음
- 스케줄링 결정 및 동기화를 위한 커널 호출 필요 X
- 인터럽트 발생 시 오버헤드가 적음
- context switch 발생 x(유저레벨 스레드 스케줄러 이용)
- 커널은 사용자 수준 스레드의 존재조차 모름 → 모드간의 전환 x, 성능 향상
2-4-2-3. 단점
- 시스템 전반에 걸친 스케줄링 우선순위 지원하지 않음(스레드의 동작 순서 보장 X)
- I/O 작업 등에 의해 프로세스에 속한 스레드 중 하나라도 block될 경우 전체 스레드가 block됨
2-5. 멀티스레드 프로그래밍(Multithreading)
2-5-1. 정의
- 단일 프로세스에 여러 스레드를 할당하는 프로그래밍 기술
- 스레드는 동시에 병렬로 실행됨
- 부모 프로세스 내에서 동일한 메모리 공간 공유
2-5-2. 장점
많은 운영체제들은 멀티 프로세싱을 지원하고 있음에도 멀티 스레딩을 기본으로 함
2-5-2-1. 프로세스보다 가벼움
- 생성 및 종료 속도가 프로세스보다 빠름
- 프로세스 내에서 생성 → 실행 환경 설정 작업이 매우 간단
- 코드, 데이터, 스택 영역을 제외한 나머지 자원을 서로 공유
→ 내장되어 있는 데이터 용량이 작아 자원 관리 비용이 감소함
2-5-2-2. 자원의 효율성
- 하나의 프로세스 내에서 여러 개의 스레드 생성
- 공유 메모리에 대해 스레드 간 자원 공유 가능
→ IPC를 사용하지 않아도 데이터를 공유할 수 있어 시스템 자원 소모량 감소
2-5-2-3. Context Switching 비용 감소
- 프로세스 : 높은 context switching 비용
- 스위칭 할 때마다 CPU 캐시에 있는 내용 모두 초기화
- 새로운 프로세스 정보를 CPU 캐시에 적재
- 스레드 : 낮은 context switching 비용
- 스위칭 시 스레드 간 공유 자원을 제외한 스레드 정보(stack, register)만 교체
2-5-2-4. 응답 시간 단축
- context switching 오버헤드가 작아 응답 시간이 빠름
- ex) 웹 서버에서 클라이언트 요청을 처리하는 경우
- 멀티 프로세스 : 각 요청마다 프로세스 생성하여 처리 → 오버헤드 증가
- 멀티 스레드 : 여러 개의 스레드가 하나의 프로세스 내에서 요청 처리 → 오버헤드 감소
2-5-3. 단점
2-5-3-1. 안정성 문제
하나의 스레드에서 문제 발생 시 다른 스레드들도 영향을 받아 전체 프로그램이 종료될 수 있음
✅ 해결 방안
- 에러 발생 시 적절한 예외 처리 구현
- 에러 발생 시 새로운 스레드를 생성하거나 스레드 풀에서 잔여 스레드를 가져와 프로그램 종료 방지 → 추가 비용 발생
2-5-3-2. 동기화로 인한 성능 저하
- 여러 개의 스레드가 공유 자원에 동시 접근 가능 → 데이터 불일치
- 스레드 간 동기화를 통해 데이터 접근 제어(자원에 대한 접근을 순차적으로 통제)
→ 병목 현상 발생으로 인한 성능 저하
✅ 해결 방안
- 임계 영역에 대해 뮤텍스 또는 세마포어 방식 활용
- 임계 영역(Critical Section) : 공유 자원을 접근하는 코드 영역
- 뮤텍스(Mutex) : 임계 영역에 진입하기 전 락(lock)을 획득하고, 임계 영역을 빠져나올 때 락을 해제하여 다른 스레드들이 접근할 수 있도록 제어하는 기법
- 세마포어(Semaphore) : 동시에 접근 가능한 스레드의 개수 지정
2-5-3-3. Deadlock(교착 상태)
다수의 프로세스나 스레드가 서로 자원을 점유하고, 다른 프로세스나 스레드가 점유한 자원을 기다리는 상황에서 무한정 대기하게 되는 상태
✅ 해결 방안
2-5-3-4. Context Switching Overhead
스레드 수가 증가할수록 context switching이 많이 발생하여 성능 저하로 이어짐
2-5-3-5. 어려운 디버깅
여러 개의 스레드가 동시에 실행되어 각 스레드의 동작을 추적하기 어려울 수 있음
✅ 해결 방안
- 스레드 간의 상호작용과 동기화 기법에 대한 깊은 이해
- 디버깅 도구 적극 활용
2-6. Thread-Safety
2-6-1. 정의
- 멀티스레드 프로그래밍에서 어떤 함수나 변수, 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없는 상태
- 하나의 함수가 한 스레드로부터 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하여 동시에 함께 실행되더라도 각 스레드에서의 함수의 수행 결과가 올바르게 나오는 것
2-6-2. 설계 방법
✅ 재진입성
어떤 함수가 한 스레드에 의해 호출되어 실행 중일 때, 다른 스레드가 그 함수를 호출하더라도 그 결과가 각각 올바르게 주어져야 함
✅ 상호배제
공유 자원을 사용해야 할 경우 해당 자원의 접근을 lock으로 통제
✅ 스레드 지역 저장소
공유 자원의 사용을 최대한 줄이고, 각각의 스레드에서만 접근 가능한 저장소들을 사용하여 동시 접근을 막음
✅ 원자 연산
공유 자원에 접근 시 원자 연산을 이용하거나, '원자적'으로 정의된 접근 방법을 사용하여 상호 배제 구현