멀티프로그래밍 작업을 할 때 프로세스는 독립적으로 작업을 하거나, 공유된 자원을 활용하여 공동작업을 하기도 한다. 멀티 프로세싱은 IPC(프로세스 간 통신방법)를 통해 자원을 공유하고, 멀티스레딩의 스레드들은 프로세스의 메모리 영역(코드, 데이터, 힙)을 공유하며 공동 작업을 한다. 자원 공유를 통해 응답성과 경제성을 높일 수 있지만 이에 따른 문제도 발생할 수 있다. 공유 자원을 동시에 여러 스레드가 접근한다면 어떤 문제가 일어날까? 2개 이상의 스레드가 공유 자원에 접근할 경우 그곳의 데이터는 온전하지 않을 수 있다. 따라서 Critical Section을 설정하여 두 개 이상의 스레드가 동시 접근을 할 수 없도록 막아야 한다. 이와 같은 동기화 문제의 해결 방법에 대해 알아보자.
<쉽게 배우는 운영체제> 책을 참고하였습니다.
Critical Section
임계 구역이라고도 하며, 둘 이상의 스레드가 동일한 프로그램의 영역을 접근하는 경우를 가리킨다. Critical Section에는 데이터 변수의 일관성을 유지하기 위해 동기화해야 하는 공유 변수 또는 Resource가 포함된다.
☆Resource의 종류 : CPU cycles, files, I/O devices(printers, drives) 등
CSP(Critical Section Problem) 해결조건
- Mutual Exclusion : Critical Section 내에는 하나의 스레드만 존재해야 함
- Bounded Waiting : Critical Section 내에 무한정으로 대기할 수 없음
- Progress Flexibility : Shared Resource가 사용 중이 아니라면 언제든 사용할 수 있어야 함
CSP 해결하기
- Concurrency를 보장할 수 있는가 (Mutual Exclusion)
- 각각의 스레드가 적당한 시간에 Critical Section에 접근 가능하고, 기아(starvation)에 빠지지 않도록 할 수 있는가 (Fairness)
- Lock을 사용함으로써 큰 Overhead가 발생하지 않는가 (performance)
Lock이란?
Critical Section은 여러 스레드에서 동시에 실행되면 안 되는 부분이다. 따라서 하나의 스레드만 접근할 수 있도록 보호하여야 하는데, lock을 통해 보호할 수 있다. 하지만 너무 많은 lock을 걸 경우 lock(), unlock()하는 데 있어 많은 Overhead가 발생한다.
- Fine-grained Lock : Critical Section마다 lock을 걸어 제한
- Coarse-grained Lock : 여러 개의 Critical Section을 묶어서 lock을 걸어 제한
싱글 쓰레드 환경에서 Fine-grained Lock이 Coarse-grained Lock보다 좀 더 성능이 좋다.
0. Interrupt Masking
void lock() {
DisableInterrupts(); //인터럽트 막기
}
void unlock() {
EnableInterrupts();
}
- Critical Section에 접근할 때 인터럽트를 막는다.
- Single Processor에서만 가능, Multi Processor에서는 동작 안 함
- 자발적으로 CPU에 권한을 양보해야 하는데, 이것을 제공하지 않음
1. Mutex Locks
- 상호 배제 문제만 해결
- 동기화를 위한 가장 간단한 툴
- Critical Section을 보호하고 race condition을 예방한다.
- race condition : 두 개의 스레드가 하나의 자원을 놓고 서로 사용하려고 할 때를 가리킴
- Busy waiting Problem
- lock이 해제되길 기다리면서 무한루프를 돔
- Spin lock이라고도 한다.
- Spin lock이 유용할 때 : waiting 하면서 CPU를 계속 점유하고 있기 때문에 Context Switching이 일어나지 않는다.
- CPU를 점유하고 있지 않다면 Wait Queue에서 Ready Queue로 가면서 시간이 오래 걸린다.
2. Semaphore
- 상호 배제 문제만 해결
- Mutex보다 좀 더 견고하고, 편리하고, 효과적인 툴
- Binary Semaphore : mutex lock과 유사
- Counting Semaphore : 여러 개의 인스턴스를 가진 자원들에게 사용할 수 있다.
- mutex와 마찬가지로 Busy waiting Problem이 있음
- wait() operation을 통해 Wait Queue에 들어가게 하고, signal() operation을 통해 Ready Queue에 들어가게 해서 Busy waiting Problem을 막을 수 있다.
3. Monitor
- 상호 배제 문제만 해결
- Mutex와 Semaphore의 단점을 해결한 툴
- wait()와 signal() Operation을 내부적으로 처리하자 → 공유자원을 내부적으로 숨기고 공유 자원에 접근하기 위한 인터페이스만 제공함으로써 자원을 보호하고 프로세스 간에 동기화를 시킨다.
- monitor-lock or intrinsic-lock
- wait() : 해당 객체의 모니터 락을 획득하기 위해 대기상태로 진입함
- notify() : signal()과 같음, 해당 객체 모니터에 대기 중인 스레드 하나를 깨움
- synchronized : 임계 영역에 해당하는 코드 블록을 선언할 때 사용하는 자바 키워드
- 해당 코드 블록(임계 영역)에는 모니터 락을 획득해야 진입 가능
4. Liveness
- 상호 배제 문제와 데드락 문제 해결
'CS > 운영체제' 카테고리의 다른 글
[IPC] Inter Process Communication (0) | 2023.12.26 |
---|---|
Dead Lock (0) | 2022.08.11 |
Multi-Process VS Multi-Thread (0) | 2022.08.03 |
Thread란 (0) | 2022.08.03 |
Process란 (0) | 2022.07.13 |