본문 바로가기

CS/운영체제

동기화(Syncronization)를 왜 해야하는데!?

초읽기

왜 동기화가 중요한지? 동기화를 왜 해야하는지!?


가정을 해보겠습니다.

상황 매우 중요한 상황 이해해야하는 상황

싱글코어에 두개의 스레드를 가진 한 프로세스 그리고 멀티태스킹이 진행중인 상황입니다. 오렌지박스1 = 5개의 불량 오렌지, 오렌지박스 2 = 2개의 불량 오렌지가 있다고 가정합시다.

오렌지박스 내부에 오렌지 상태가 나쁜 애들을 골라서 갯수를 세줘야 하는 상황이고, 그 박스는 2개이며 한 박스를 한 스레드마다 맡겨둔 상황입니다. 그렇다면 결과적으로 7개를 카운트 해줘야합니다.

하지만 오류가 발생할 수 있습니다.

프로그래밍 언어는 오로지 개발자에 맞춰진 언어 이기 때문에 CPU가 이해하지 못하는 언어이므로 CPU에게 맞춰진 언어로 번역이 됩니다. 그 상황에서 CPU언어로 쓰자면 이렇습니다.

orangeBox = 2

첫줄은 메모리에 있는 변수 값(State)을 R1이라는 CPU안에 포함된 데이터를 저장하고 레지스터로 적재한 뒤에 레지스터는 += 1인 상태가 되고, 레지스터로 변수(State)에 저장을 다시 해줍니다.

이렇게 되기만 하면 이상적인 상황이 이루어지지만 그렇지 않을 수 있습니다.

첫번째 스레드가 increment를 호출하고 공유변수(State)는 현재 0인 상황입니다. 공유변수 값을 레지스터1에 로드하고,
두번째 줄 레지스터에 += 1 을 하고, 변수(state)에 저장하기 전 상황에서 컨텍스트 스위칭이 발생하게 됩니다.
(현재 레지스터1에 저장되지 않은 상태, 더해주기만 한 상태 즉 레지스터1 == 1)

두번째 스레드가 increment를 호출하고 첫번째 스레드와 같은 과정을 거친 후, 변수(state)에 1을 저장하여 공유변수(state)의 상태는 1이 된 상태입니다. 그 후에 컨텍스트 스위칭이 다시 발생하게 되어서

첫번째 스레드가 실행하는 상황에서 현재 두번째 스레드가 state += 1을 해준 상황이라 1에서 추가를 해줘야 하지만 컨텍스트 스위칭이 되기 전에 첫번째 스레드는 공유 변수의 상태가 0인 상황에서 +1을 해줬기 때문에 그대로 진행되어 의미없는 과정을 겪게 됩니다.
(이미 1이 저장되어 있어서 다시 1을 저장하는 상황이 발생)

이런 상황에서는 언제 컨텍스트 스위칭이 발생하느냐에 따라서 결과값에 문제가 발생하게 됩니다.


그래서 나왔다!!

이러한 상황을 꺾기 위해서 동기화(Syncronization)이 나오게 되었습니다!
여러 프로세스와 스레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것을 의미합니다.

이렇게 하기 위해서는 CPU 내부 언어에서 컨텍스트 스위칭이 발생되지 않게 하면 되지 않을까요?
싱글코어에서만 가능한 전략이기 때문에 사용될 수 없습니다.

한 메소드를 한 스레드만 실행하게 하는 방식을 사용하면 어떨까요?
멀티코어에서도 사용가능하고, 좋은 전략이다 그래서 임계영역(Critical Section)이라는 것이 나오게 됐고
공유 데이터의 일관성을 보장하기 위해서 하나의 프로세스 스레드만 진입해서 실행가능한 영역을 만든다!

임계영역(Critical Section)의 조건

  • 상호배제(Mutual Exclusion)
  • 진행(Progress)
  • 한정된 대기(Bound Waiting)

 

reference

https://www.youtube.com/watch?v=vp0Gckz3z64