본문 바로가기

별걸다하는 IT/운영체제 OS

[운영체제]동기화 Synchronization 문제, Race Condition

반응형

운영체제에서 Synchronization 동기화란?


동기화는 저번 포스트 IPC의 shared memory 얘기하면서 잠깐 언급했었는데 기억하시나요?

다시 한 번 정리하자면 두 개의 프로세스 A, B가 shared memory를 이용을 해가지고 데이터를 주고 받는데 A가 쓰면 B가 읽어가야 하는데 A가 여기다가 쓰고 난 뒤인지 쓰기 전인지 알 수 있는 방법이 없잖아요 그래서 A가 나 다 썼어! 라고 알려줘야 B가 shared memory에서 읽어간다고 했었죠!


"즉 이와 같이 프로세스 또는 스레드들이 수행되는 시점을 조절하는 것을 Synchronization이라고 합니다."


좀 더 확실하고 상세한 이해를 위해 동기화 문제의 예시를 하나 들면서 설명해볼게요

자 남자친구하고 여자친구하고 은행의 계좌를 공유한다고 합니다. 지금 현재 잔액이 100만원이 있어요. 남자친구도 체크카드를 가지고 있고 여자친구도 체크카드를 가지고 있는데 우연히 동시에 다른 ATM기기에 가서 돈을 찾았어요.

10만원을 이 10만원을 인출하는 거래가 동시에 은행으로 가겠죠 은행으로 이 거래가 가면 이 거래를 처리할 프로세스 스레드가 생길거예요. 동시에 찾아서 우연히 동시에 생겼다고 가정을 합시다.


1
2
3
4
5
6
7
int withdraw(account, amount) //해당 account에서 amount만큼 인출하는 함수 
{
     balance = get_balance(account); //계좌에서 현재 잔액을 가져옴
     balance = balance -amount; //남은 잔액은 기존 잔액에서 amount만큼 뺀 금액
     put_balance(account, balance); //account에 변경된 잔액을 갱신함
     return balance;
}
cs


그럼 이 withdraw 라는 함수를 수행하는 스레드가 동시에 두 개가 생성이 됩니다. 자 3번째 줄을 시행했을 때 balance는 100만원입니다. 그리고 4번째에서 실제 인출이 일어나므로 잔액은 90만원이 됩니다. 근데 4 line까지 수행이 되고 이 잔액을 업데이트 하기 전에 interrupt가 걸렸어요 인터럽트는 얼마든지 걸릴 수 있죠 가장 흔하게 딱 timer 인터럽트가 걸렸다고 가정하고 문제를 살펴봅시다.


인터럽트가 걸리면 인터럽트 핸들러가 수행이 되고 운영체제가 수행이 되죠. 운영체제가 자기 할 일을 다 처리한 후에 CPU에 프로세스를 다시 올리려고 스케줄링을 합니다. 딱 봤더니 프로세스가 두 개가 있네요 근데 아까 남자친구의 프로세스는 4 line까지 처리를 조금 완료했죠? 그래서 여자친구의 것이 스케줄링이 됩니다. get_balance를 하면 90만원이 나와야 하는데 아까 남자친구 프로세스에서 put_balance를 이용해서 업데이트 하기 전에 인터럽트가 일어나버려서 100만원이 현재 잔액으로 나오게 됩니다.

그래서 여자친구가 인출하게 되면 실질적으로 인출된 돈은 20만원인데 잔액은 90만원이 되는 것! 이런 일이 일어나면 당연히 안되겠죠?! 은행은 망할거예요. 이러한 문제를 동기화 조취를 취하지 않았을 때 일어나는 synchronization problem이라고 합니다.


즉, multi-threaded program이 되었던, multi-process program이 되었던간에 어떤 shared data를 접근하는 경우에 그들의 순서를 조절하는 것을 SYNCHRONIZATION이라고 합니다.


남자친구와 여자친구가 동시에 인출을 할 때 이런 순서로 Context Switching이 되면서 수행이 되면 문제가 발생!


↓중간광고 스을쩍ㅎㅎ 작업 중 당충전 초콜릿 하나 감사합니다. 충전100프로로 보답하는 200프로 퀄리티!



Race Condition이란?


두 개 이상의 concurrent한 스레드들이 공유된 자원에 접근하려고 할 때 동기화 메커니즘 없이 접근하려고 하는 이런 상황을 race condition이라고 합니다. race가 경쟁하는 거잖아요 두 개의 스레드가 하나의 자원을 놓고 서로 사용하려고 경쟁하는 상황이 race condition!


이런 race condition인 경우에는 스레드의 실행 순서를 잘 조절해주지 않으면 이상한 상태, 비정상적인 상태가 나오게 됩니다. 이 문제는 항상 발생하는 게 아니라 아까처럼 그 특정한 순서로 수행되었을 때만 발생하게 되는거라 더 골치가 아픕니다. 하필 남자친구와 여자친구가 동시에 요청을 했고 거기에 하필 그 순간에 재수없게 timer interrupt가 발생을 해서 그렇게 된거죠.

한마디로 동시에 인출했어도 인터럽트가 그 순간에만 걸리지 않았어도 문제는 없었을거라는 이야기.


골치가 아픈 이유는, 이 말은 프로그램 개발시 디버깅 시에는 문제점이 전혀 보이지 않는다는 뜻이기 얘기기 때문입니다. 이러한 상황이 발생되지 않는 한 내가 제대로 개발했네 라고 착각을 하게 되는거죠. 근데 이 프로그램을 365일 돌리다가 우연이 저런 경우가 발생하게 되면 그거는 더 큰일이 되는 겁니다. 이미 상용되서 많은 사용자들이 사용하고 있을 경우, 이 문제는 진짜 큰 문제인거죠!


그래서 멀티스레드 프로그래밍을 할 경우에는 특히 동기화 문제를 꼭 고려해주어야 합니다. 중요중요!


반응형
  • 궁금해요 2019.10.24 23:50

    글 잘보고 있습니다^^

    여자친구와 남자친구의 요청이 같은 함수의 변수에 접근하기 때문에 동기화 문제가 발생하잖아요?
    이걸 Context Switching에 비유하셨는데 Context Switching은 "Process"끼리의 전환을 의미하는거 아닌가요?

    지금 설명하는 Synchronization이나 Race Condition은 Multi-"thread"에 관한 내용 아닌가요?