Test와 Set을 한 번에 수행하는 기계어
Machine instruction
- Atomicity, Indivisible
- 실행 중 Interrupt를 받지 않음 (preemption이 되지 않음)
Busy waiting
- Inefficient
- ME with TAS instruction
- 3개 이상의 프로세스의 경우, Bounded waiting 조건 위배
- N-Process mutual exclusion
장점
- 구현이 간단
단점
- Busy waiting -> Inefficient
Busy waiting 문제를 해소한 상호배제 기법
- Semaphore : 대부분의 OS들이 사용하는 기법
2.1. Spinlock
2.2. Semaphore
2.3. Eventcount / Sequencer
※ Spinlock
- active = 1 : 임계 지역을 실행중인 프로세스 없음
- active = 0 : 임계 지역을 실행중인 프로세스 있음
- 초기화 연산 : S 변수에 초기 값을 부여하는 연산
- P(), V() 연산
- 모두 Indivisible 연산
- OS support
- 전체가 한 instruction cycle에 수행 됨
- active = 1 : 임계 지역을 실행중인 프로세스 없음
- active = 2 : 임계 지역을 실행중인 프로세스 없음
3. 생산자-소비자 문제 (Producer-Consumer problem)
- 생산자-소비자 문제 with single buffer
- 생산자-소비자 문제 with N-buffers
4. Reader-Writer 문제
Reader : 데이터에 대해 읽기 연산만 수행
Write : 데이터에 대해 갱신 연산을 수행
데이터 무결성 보장 필요
- Reader들은 동시에 데이터 접근 가능
- Writer들(또는 reader와 write)이 동시 데이터 접근 시 , 상호배제(동기화) 필요
- Reader preference solution
No busy waiting -> pro
- 기다려야 하는 프로세스는 block(asleep) 상태가 됨
Semaphore queue에 대한 wake-up 순서는 비결정적 -> con
- Starvation problem
은행의 번호표와 비슷한 개념
Sequencer
- 정수형 변수
- 생성시 0으로 초기화, 감소하지 않음
- 발생 사건들의 순서 유지
- ticket() 연산으로만 접근 가능
ticket(S)
- 현재까지 ticket() 연산이 호출 된 횟수를 반환
- Indivisible operation
Eventcount
- 정수형 변수
- 생성시 0으로 초기화, 감소하지 않음
- 특정 사건의 발생 횟수를 기록
- read(E), advance(E), await(E, v) 연산으로만 접근 가능
read(E)
- 현재 Eventcount 값 반환
advance(E)
- E <- E + 1
- E를 기다리고 있는 프로세스를 깨움 (wake-up)
await(E, v)
- V는 정수형 변수
- if (E < v) 이면 E에 열견될 QE에 프로세스 전달(push) 및 CPU scheduler 호출
- Mutual exclusion
- Producer-Consumer problem
No busy waiting
No starvation
- FIFO scheduling for Qe
Semaphore 보다 더 low-level control이 가능
- 자원 R 사용 가능
- 모니터안에 프로세스 없음
- 프로세스 Pj가 모니터 안에서 자원 R을 요청
- 자원 R이 Pj에가 할당 됨
- 프로세스 Pk가 R 요청, Pm 또한 R 요청
- Pj가 R 반환
- R_Fee.signal() 호출에 의해 Pk가 wake up
- 자원 R이 Pk에게 할당 됨
- Pj가 모니터 안으로 돌아와서, 남은 작업 수행