한 번에 한 process가 접근할 수 있도록 만들어주는 scheme이다.
공유 data를 구성하기 위해서 동기화가 필요하다. 그 동기화는 어떤 기법이 있는가?
hardware적인 solution과 software적인 solution
<software> Pterson의 solution
program에 의해 locking을 하게 되면(동기화하면) overhead가 클 수도 있고, 동기화 program 자체에서도 또 동기화를 시켜주어야 한다. 실질적으로 사용하기에 쉽지 않다.
<hardware> hardware instruction으로 동기화가 가능
'test and set'과 'compare and swap'과 같은 instruction은 속도는 빠르지만 user 입장에서는 사용하기에 어렵다는 단점이 있다. busy waiting과 같은 문제가 발생할 수 있다.
<software> 그래서 더 정교한 software적 solution
Mutex Locks과 Semaphores, Monitors가 있다. Monitor는 지원하는 language가 있고, C같은 경우 Monitor를 지원하는 API가 없기 때문에 Monitor처럼 만들고 싶다면 Semaphore와 같은 것을 이용해서 별도 구현을 해야 한다.
왜 공유 data인 경우에 race condition이 발생하는가? 상호 배제(mutual exclusion)는 왜 필요한가?
critical section 사이에서 data 일관성을 유지하기 위해 mutual exclusion을 통한 동기화를 해주어야 한다.
counter는 producer나 consumer가 둘 다 접근하는(수정 가능한) 공유 data다. 이 부분을 동기화 해주어야 한다.(한 번에 한 프로그램만 수정 가능하도록)
다음의 두 입장을 보도록 한다.
Producer 입장
while(true) {
/* produce an item in next produced */
while(counter == BUFFER_SIZE);
/* do nothing */
buffer[in] = next_produced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
- counter == BUFFER_SIZE인 경우 => 빈 BUFFER가 없는 경우(buffer slot이 없는 경우) 있을 때까지 기다린다.
- in은 다음 버퍼 index를 가리킨다.
- 마지막으로 count 값을 증가
Consumer 입장
while(true) {
while(counter == 0); // 빈 buffer의 경우 소비할 data가 없으니 소비할 data를 기다린다.
/* do nothing */
next_consumed = buffer[out]; // buffer가 있으면 data를 이처럼 만든다.
out = (out + 1) % BUFFER_SIZE; // 다음 buffer index
counter--; // counter 감소
/* consume the item in next consumed */
}
producer는 counter의 값을 1 증가시킨다.
consumer는 counter의 값을 1 감소시킨다.
예를 들어 맨 처음 counter는 5였다고 하자.
- producer가 5의 값에서 1 증가시키면 6이 되고 consumer가 줄이면 다시 5가 된다. ( 5 -> 6 -> 5 )
- consumer가 먼저 수행하고 producer가 수행했다면 5 -> 4 -> 5가 될 것이다.
누가 먼저 수행하든 최종 결과는 5로 일관성 있는 결과가 나타나야 한다. (data consistency)
(Race Condition) 그런데 만약 두 개의 process가 동시에 counter의 값을 증가, 감소하려 하면 전혀 다른 값이 나올 수 있다.
여기서 counter 부분을 임계 구역(critical section)이라 한다.
그래서 한 번에 한 process만 critical section에 들어갈 수 있도록 하는 것(Mutual exclusion)이 필요하다.
'운영체제' 카테고리의 다른 글
| Semaphores (0) | 2022.07.21 |
|---|---|
| Mutex Locks (0) | 2022.07.21 |
| 시스템 콜(System call) (0) | 2022.07.21 |
| 인터럽트(interrupt) (0) | 2022.07.21 |