공유자원을 활용한 로직의 문제는 어떤 것들이 있나?

다음과 같은 문제가 있다.

 스레드1

 스레드2

 

 전역변수 A에 10 할당

 

 전역변수 A는 10을 저장

 

 전역 변수 A에 20할당

 전역변수 A는 20을 저장

 전역변수 A의 값 출력

 

 전역변수 A는 20을 출력


스레드1이 A에 분명 10을 할당했는데, 후에 바로 스레드2가 20을 할당해버리므로

예상치 못한 결과를 얻어낸다.


공유 자원에 대한 접근 문제 

= Critical Section(임계 구역)에 대한 접근 문제

공유자원을 사용하는 메커니즘에 LOCK이 있다.

이 메커니즘을 이해하기 위해서 뮤텍스와 세마포어에 대한 개념을 알아야한다.


뮤텍스와 세마포어의 차이는 무엇인가?

공유자원에 대한 접근권한, Lock이라는 키를 한 개만 가지고 있는 것은 뮤텍스(mutex)이다.

반면에, Lock이라는 키를 여러 개 가질 수 있는 것은 세마포어(Semaphore)이다.


뮤텍스란 무엇인가?

일종의 Locking 매커니즘이다. lock을 가지고 있을 때만 공유 데이터에 접근이 가능하다.

화장실에 갈 때 키를 가진 사람만이 갈 수 있다. 일을 다 본 후에는 키를 반납하고 그 다음 사람이 갈 수 있다. 이러한 메커니즘을 말한다. 

유의할 점은 lock에 대한 소유권이 있다는 점. 열쇠를 획득한 사람만 반납 할 수 있다.


세마포어란 무엇인가?

세마포어는 동시에 리소스에 접근 할 수 있는 “허용 가능한 counter의 개수”를 말한다.

예를 들면 병원에 있는 어느 한 병실에 5명까지 들어 갈 수 있다고 한다면, 5명까지 들어 갈 때 counting을 하고 5명 이후에는 밖에서 기다려야 한다. 한 사람이 나오게 되면 다음 사람이 들어 갈 수 있게 되는 것이다.

그 count수에 따라서 1개이면 binary semaphore, 여러 개이면 counting semaphore라고 한다.

binary semaphore는 뮤텍스와 개념적으로 같다.


모니터(monitor)란 무엇인가?

뮤텍스(mutex)Condition Valuable(Queue라고도 함)을 가지고 있는 Synchronization 메커니즘이다.

예를 들어 자바에서 모든 객체는 Object 클래스를 상속 받는다. 이 Object 클래스에는 wait(), notifyAll(), notify() 메소드를 가지고 있는데 이게 바로 Condition Variables 역할이라고 보면 된다. 고로 모든 자바 객체는 Monitor를 가지고 있다.

자바에서는 Mutual Exclusion 해결을 위한 구현체로 Synchronized 키워드가 있다. 예를 들어 Synchronized가 메소드에 선언되어있고, 쓰레드A가 이미 Lock을 획득해서 Critical Section(메소드)을 수행중이라고 가정하자. 쓰레드B가 동일한 메소드를 수행하기 위해 해당 Object의 Lock을 획득해야 할 것이다. 이 Lock이 반환될 때까지 대기를 해야하는데 그 때 사용되는게 바로 Monitor다. 쓰레드A가 Lock을 반환하면 쓰레드B는 기다렸다가 Lock을 획득하게 된다. 그리고 Critical Section인 메소드를 수행할 수 있게 된다. 물론 Synchronized 키워드를 사용했을 때 자동적으로 수행되는 내부 동작이고, 별도로 명시적인 Monitor를 구현할 수도 있다.(이건 길어질거 같으니 별도 포스팅으로….) 아무튼 Monitor는 이렇게 Mutex(Lock)과 Condition Variables을 이용해서 Mutual Exclustion을 해결하고 있다. 그 외 Monitor의 다른 정의로는 공유자원에 안전하게 접근하기 위해 Mutual Exclusion가 랩핑된 Thread-Safe한 클래스, 객체, 모듈들을 의미하기도 한다.


레이스 컨디션(race condition)이란 무엇인가?

경합조건이라고 하며, 유닉스 계열의 시스템에서 여러개의 프로세스가 동시에 실행될 때, 서로 CPU에 대한 우선권을 차지하기 위해 경쟁하게 되는데, 그것이 바로 레이스 컨디션이다. 이것은 규칙적인것이 아니라 불규칙하게 이루어진다. 이를 이용해 해킹에 사용되기도 한다.


스핀락이란 무엇인가?

스핀락은 위 CriticalSection의 한가지 단점을 극복하는데서 착안된 동기화 기법이다.

그것은 바로 쓰레드가 임계 영역을 획득하지 못하게 되면(Lock을 못잡게 되면) 쓰레드가 블로킹되는 것이다. 쓰레드 블로킹은 이후 쓰레드 컨텍스트 스위칭을 불러오게 되며 성능의 하락을 유발시킨다.

이 단점을 극복하기 위해 스핀락은 락을 점유하지 못할 때 쓰레드가 Back-off 되어 다른 쓰레드에게 넘기는 것이 아니라, Loop를 돌면서 해당 쓰레드를 Busy-Waiting 상태로 만들어 버린다.

그러면, 쓰레드 스위칭이 발생하지 않게 되어 컨텍스트 스위칭이 발생하지 않게 되는 것이다.

하지만!!!

임계 영역에서의 작업이 다소 시간이 오래 걸리는 일이라면?

결과는 오히려 CriticalSection을 사용할 때보다 훨씬 더 안 좋아지게 된다.

곧 끝날거라 기대하며 기다리느라 쓰레드가 헛돌고 있다보면 CPU 점유율이 올라가고, 오히려 다른 쓰레드가 컨텍스트 스위칭을 하더라도 일을 더 많이 할 수 있다면 낭비가 되는 것이다.


바쁜 대기(busy waiting)이란 무엇인가?

대기중인 스레드가 여전히 활성 상태긴 하지만 실제로는 아무 일도 하지 않는 것을 말한다.


생산자 소비자 문제란 무엇인가?(동시성을 처리하는 방법에 대한 문제)


철학자들의 저녁식사 문제란 무엇인가?(동시성을 처리하는 방법에 대한 문제)




'OS' 카테고리의 다른 글

프로세스의 상태(state)  (0) 2015.08.01
컨텍스트 스위칭 - Context Switching  (0) 2015.07.31
동기와 비동기  (0) 2015.07.31
프로세스와 스레드 차이  (0) 2015.07.31
데드락 교착상태  (0) 2015.07.31
Posted by slender ankles
,