안녕하세요? 허니입니다. 운영체제에서 프로세스끼리 자원경쟁을 한다거나 서로 자원을 쓰지 못하는 기아현상을 해결하기 위해 동기화 기법을 활용합니다. 즉, 자원을 효과적으로 활용하기 위한 정책으로 프로세스 동기화에 자세히 포스팅 하려고 합니다. 학생이나 연구원분들에게 많은 도움이 될 것이라고 생각하며 언제든지 질문은 환영입니다.
오늘의 주제
프로세스 동기화(Process Synchronization)
Mutual exclusion |
Semaphore |
Monitor |
Process Synchronization
동기화(Synchronization)
여러 프로세스의 접근이 가능한「공유된 데이터」에 여러 프로세스들이 동시에 접근했을 경우 과연 어떠한 문제가 발생하게 될까. 체계적인 접근방법을 만들어 놓지 않는다면 예측하지 못했던 결과가 나올 가능성이 있다. 이러한 가능성을 배제하기 위해 Synchronization의 개념이 도입되었다. 예를 들어 은행에 1000원의 잔고가 남아 있다고 하자. 통장의 주인이 500원을 찾는 순간 동시에 고향 어머니께서 500원을 송금해 오셨다면 어떤 결과가 발생할까. 우리가 바라는 결과값은 두말할 나위 없이 바로 1000원인데 말이다. 그러나 그 결과값이 500원이 나왔다면 또는 1500원이 나왔다면 이것은 엄청난 문제가 아닐 수 없다. 어떻게 이런 결과값이 나올 수 있었을까. 바로 공유 데이터, 은행 잔고 1000원에 A프로세스(500원 인출)와, B프로세스(500원 송금이 동시에 접근해 각각의 프로세스가 서로 다른 결과를 갖고 있기 때문이다.
그림 18 Synchronization의 필요성
위의 그림과 같이 A프로세스는 500원의 결과를 B프로세스는 1500원의 결과를 갖고 있을 경우 마감 처리되는 프로세스의 결과가 최종 은행잔고로 남게 되는 것이다. 어떠한 데이터에 대해 동시 작업이 일어났을 경우 처리순서에 상관없이 원하는 결과값을 얻기 위해 바로 Synchronization이 필요한 것이다. 즉, Synchronization의 목적은 data consistency을 보장해 주는 것이다. 하나의 작업을 처리하는데 100개의 시그널이 동시에 날아와 제 각각의 처리를 마쳐도 데이터는 항상 시종일관 자신이 갖고 있어야 할 결과값을 담고 있어야 하는 것이다. data consistency을 보장해 주기 위한 방법은 다음과 같다.
상호배제(Mutual exclusion)
공유 데이터에 동시에 여러 개의 프로세스가 임의로 접근하게 되면 앞서 살펴본 예와 같이 데이터의 상태가 부정확하게 되는 문제가 발생된다. 그렇기에 공유데이터가 하나의 프로세스에 의해 독점적으로 사용되는 원칙을 상호배제라 한다. 여기서 잠깐 critical section이라는 코딩 용어를 알아두자. 바로 상호배제의 원리가 지켜져야 하는 영역이 critical section인 것이다. 자칫 잘못하면 위험한 결과가 초래될지도 모르기에 위험한 세션이라 이름을 붙인 것일까....
예를 들어 프로그래머가 다음과 같이 코딩을 하였다.
entry section critical section exit section |
프로세스는 critical section안으로 들어가기 이전 entry section 단계에서 출입을 허가 받아야 한다. 이러한 허가절차를 받는 이유는 critical section안에 오직 하나의 프로세스만이 존재하도록 하기 위해서다. 프로세스를 이렇게 순차적으로 접근시킨다면 동시에 2개 이상의 프로세스가 접근해 서로 다른 결과치를 갖게 되는 문제가 해결되는 것이다. 다시 말해 A프로세스가 최종결과로 시스템 내부에서 처리되면 통장에는 500원의 잔고가 남을 것이고 B프로세스가 최종결과로 시스템 내부에서 처리되면 통장에는 1500원의 잔고가 남을 것이다. 이러한 문제의 발생을 막기 위해 A프로세스가 -500을 수행하는 동안 +500을 수행하는 B프로세스의 접근을 차단시키는 것이다. 그 역할을 바로 entry section이 맡고 있는 것이다. 이러한 상호배제(Mutual exclusion)는 DB의 프로그램에서는 자동적인 부가기능으로 지원되지만 OS의 경우는 사용자의 요구에 따라 지원된다. DB프로그램은 공유된 데이터의 보장이 프로그램의 가장 중요한 요소이다. 모든 프로그램이 수행될 때 공유된 데이터를 바탕으로 사용되기 때문이다. 그러나 OS는 사용자의 요구에 따라 상호배제(Mutual exclusion)가 지원된다. 바로 그 필요성이 DB만큼 막대하지 않기에 사용자의 필요성에 맡기는 것이다. 은행을 운영하는데 있어 CCTV등의 보안장치는 필수불가결하기 때문에 전국 어느 은행이나 설치를 했겠지만 보통의 가정집은 집주인이 필요하다고 판단되면 설치되는 것처럼 말이다.
상호배제(Mutual exclusion)의 장점은 무엇보다도 혼란이 없고 간단하다는 점이다. 그러나 매우 커다란 문제점이 내재되어 있었다. 바로 read와 write의 처리에 관한 문제였다. 「공유 데이터」에 read라는 명령어를 수행하기 위해 접근하는 프로세스는 100개나 1000개가 동시에 critical section안으로 들어와도 아무런 문제가 없다. 그 프로세스들을 공유된 데이터를 다만 참조할 뿐 더 이상의 어떤 변화도 가져오지 않기 때문이다. 그러나 write라는 명령어를 수행하기 위해 접근하는 프로세스의 경우는 1개만이 critical section 안에서 처리되어야 한다. write는 공유 데이터를 변화시키기 때문이다.
그러나 상호배제(Mutual exclusion)의 방법에서는 바로 이러한 read와 write의 처리를 구분 짓지 않는다. 무조건 「공유 데이터」에 접근하기 위해선 1000개가 동시 처리되어도 좋을 read마저도 오랜 기다림을 가져야 했다. 그렇기에 시스템 설계자는 새로운 무엇을 찾아내려 했다. 그 방법은 바로 kernel 자체가 하나의 커다란 critical section의 역할을 하는 것이다.
그림 19 kernel 자체의 critical section
여기서 가장 핵심이 되는 것은 lock이란 개념이다. 우리말로 표현한다면 잠금장치, 즉 자물쇠인 것이다. 바로 lock이라는 용어는 남이 접근하지 못하도록 잠궈 놓는다는 의미를 갖고 있는데 하나의 프로세스가 공유데이터에 접근하는 동안 다른 프로세스가 공유데이터에 접근하지 못하도록 입구를 잠궈 두는 것이다. lock에는 spin lock과 sleep lock이 있는데 spin lock이 0일 때는 critical section에 프로세스가 들어와도 된다는 것을 의미하고 spin lock이 1일 때는 critical section안에 다른 프로세스가 들어와 있다는 것을 의미한다. spin lock이 1일 경우 다음 수행을 기다리는 프로세스는 1이 언제 0이 될까를 관찰하며 Lock을 계속 돌게 된다. 바로 exit section에 의해 critical section내에서 프로세스가 처리되었다는 것이 인식되어 spin lock을 0으로 만드는 것이다.
그림 20 spin lock
sleep lock은 lock이 1일 경우 기다리던 프로세스는 sleep을 하게 되는 것이다. critical section내에 프로세스가 언제 처리가 끝날지 모르기 때문이다. critical section내에 프로세스의 작업이 끝나게 되면 sleep중인 프로세스를 깨워 처리하게 된다.
그림 21 Sleep Lock
그러나 이러한 방법 또한 완벽한 것은 아니었다. 또 다시 발생한 문제점은 동시에 2개 이상의 프로세스가 접근해 0을 1로 바꿀 가능성이 있다는 것이었다. 이러한 상황은 하나 이상의 프로세스가 동시에 lock=1에서 lock=0으로 바뀐 변수를 확인한 경우 발생하게 된다. 바로 프로세스가 처리될 때 0을 read해 1로 write하는 작업이 따로 수행되기 때문이다. 예를 들어 프로세스A와 프로세스B가 동시에 lock=0인 것을 read했다. 그러나 프로세스B가 먼저 lock=1을 write하고 프로세스B는 read만을 한 채 더 이상 작업이 진행되지 않았다. 이럴 경우 프로세스B는 context switching이 일어나게 되고 그 다음 작업이 수행될 때는 read작업을 다시 하지 않는다. 그렇기에 context switching이 발생하기 이전 lock=0이었던 것만을 기억한 채 작업을 수행하기 때문에 현재 lock=1이 라도 프로세스는 데이터에 접근하게 되는 것이다. 바로 또다시 동시에 2개 이상의 프로세스가 접근해 서로 다른 결과값을 갖게 되는 근본적인 문제가 다시 발생되는 것이다. 이러한 문제의 가장 간단한 해결책은 read/write를 하나의 명령어로 만들어 놓는 것이다. 이렇게 되면 동시에 2개의 프로세스가 lock을 0으로 볼 리는 없는 것이다.
요점정리
Synchronization은 왜 필요한가
여러 프로세스의 접근이 가능한「공유된 데이터」에 동시에 여러 프로세스들이 접근했을 경우 어떠한 접근체계를 만들어놓지 않는다면 예측하지 못했던 결과가 나올 가능성이 있다. 이러한 가능성을 배제하기 위해 Synchronization의 개념이 도입되었다.
바로 Synchronization의 목적은 data consistency을 보장해 주는 것이다.
하나의 작업을 처리하는데 100개의 시그널이 동시에 날아와 제 각각의 처리를 마쳐도 데이터는 항상 시종일관 자신이 갖고 있어야할 결과값을 담고 있어야 하는 것이다.
data consistency을 보장해 주기 위한 방법
1)상호배제(Mutual exclusion) - 공유데이터가 하나의 프로세스에 의해 독점적으로 사용되는 원칙을 상호배제라 한다.
2)kernel을 이용 - spin lock과 sleep lock을 이용하여 kernel 자체가 critical section 역할을 하게 된다.
목 차 |
운영체제 메모리 관련해서 알아야 할 개념은 어떤것이 있나요? (TLB, Locality, Working Set, Overlay) |
운영체제 디스크 공간 할당(Disk Space Allocation) 알고리즘과 효과적 알고리즘의 판단 기준은? |
'Past Material' 카테고리의 다른 글
운영체제 메모리 관리(Memory Management)는 어떻게 하나요? (0) | 2019.05.13 |
---|---|
운영체제에서 세마포어(Semaphore)란? (0) | 2019.05.13 |
운영체제 스케줄링 알고리즘의 비교 기준이 있나요? (0) | 2019.05.13 |
운영체제 스케줄링 (Scheduling)은 어떻게 하나요? (0) | 2019.05.13 |
운영체제 스레드(Thread)는 무엇인가요? (0) | 2019.05.13 |