본문 바로가기
대딩/운영체제

동기화_Race condition, Synchronization

by 경아ㅏ 2022. 6. 14.

Synchronization Problem(Critical Section Problem)

 

일반적으로, 여러 프로세스(쓰레드)는 데이터를 공유하여 사용합니다. 이 때, 여러 프로세스(쓰레드)가 공유 자원에 동시에 접근하게 된다면 비의도적으로 공유 자원의 값이 변경되거나 오염될 수 있습니다. 이러한 상황을 Race condition이라고 하는데, 두 예시를 통해 해당 상황을 자세히 설명해보겠습니다.

 

공용 계좌에서의 인출

사람 A와 B가 잔액이 100만원인 공용 계좌를 가지고 있고, 각각 10만원씩 인출하려고 합니다.

 

계좌에서 특정 금액을 인출하는 과정은 다음과 같습니다.

 

void withdraw(account, amount) {
    balance = get_balance(account); //계좌 잔액 불러오기
    balance -= amount; //새 잔액 게산하기
    put_balance(account, balance); //업데이트 된 잔액 반영하기
}

 

해당 코드는 문제가 없어보입니다. A와 B가 각각 10만원을 인출한다면 잔액은 80원이 될 것이라 예측됩니다. 하지만, 해당 코드에는 치명적인 오류가 있습니다.  Multiprocess 환경에서는 언제든지 context switching이 일어날 수 있고, 그 시점에 따라 각각의 코드 섹션이 교차 배치 될 수 있기 때문입니다.

 

예를 들어, 코드들이 다음과 같이 스케줄링 된다면 결과적인 잔액 금액은 80만원이 아닌 90만원이 됩니다.

 

 

 

Bound Buffer(Produce-Consumer)

 

Producer와 Consumer는 데이터를 저장하는 buffer와 count 변수를 공유하고 있습니다.

 

 

Producer는 버퍼에 빈자리가 생길 때까지 기다렸다가, 데이터를 버퍼에 넣고 count를 1 증가시키는 프로세스입니다.

Consumer는 버퍼에 데이터가 채워질 때까지 기다렸다가, 데이터를 버퍼에서 추출하고 count를 1 감소시키는 프로세스입니다. 

 

해당 예시도 언뜻보면 괜찮아보이지만, context switching의 시점에 따라 count의 변수의 값이 비의도적으로 계산될 수 있습니다.

 

count++은 기계어로 변환하면 다음과 같고,

 

register1 = count;
register1 += 1;
count = register1;

 

count--를 기계어로 변환하면 다음과 같습니다.

 

reigster2 = count;
register2 -= 1;
count = register2;

 

버퍼에 데이터가 5개 들어가 있고 count = 5 일때, Producer와 Consumer를 각각 한번씩 실행하면 count는 여전히 5로 남아야 합니다. 그러나, count++ 과 count-- 의 수행이 다음과 같은 순서로 이루어진다면 count의 값은 뜬금 없이 4로 남게 됩니다.

 

register1 = count; //count = 5
register1 += 1; //count = 5, register1 = 6

------------------------------------------------ context switching

register2 = count; //count = 5, register2 = 5
register2 -=1; //count = 5, register2 = 4

------------------------------------------------ context switching

count = register1; //count = 6
count = register2; //count = 4

 

다시 정리해본다면,

Race condition 이란, 프로세스(스레드)들이 공유 자원에 동시에 접근하여 비의도적으로 공유자원의 값이 변경되거나 오염되는 상황을 말합니다. 이러한 상황을 막기 위해 등장한 것이 Synchronization(동기화) 입니다.

 

 

Synchronization의  3가지 조건

 

Synchronization은 다음과 같이 구현됩니다.

 

1) Mutual Exclution: 어떠한 프로세스가 critical section을 실행하고 있을 때, 다른 프로세스는 critical section을 수행할 수 없습니다.

2) Progress: 어떠한 프로세스도 Critical section을 실행하고 있지 않을 때, 이를 실행하고자 하는 프로세스가 바로 진입합니다.

3) Bounded waiting: 어떠한 프로세스가 Critical section을 실행하고 있을 때, 다른 프로세스는 대기를 수행합니다. 그러나, 이 대기는 무한하지 않아야 하며 언젠가는 Critical section을 수행할 수 있어야 합니다.

댓글