티스토리 뷰

개요

여러 프로세스 혹은 스레드가 동시에 같은 데이터를 조작하는 작업을 할 때 타이밍이나 접근 순서에 따라 그 결과 값이 들쑥날쑥 달라질 수 있다. 이러한 상황을 경쟁 조건 (Race Condition) 이라고 한다. 이러한 경쟁 조건에서 데이터 일관성을 지키는 방법으로 여러 동기화 (Synchronization) 작업을 제공한다.

 

경쟁 조건 (Race Condition)
여러 프로세스나 스레드가 동시에 공유되는 데이터 영역을 접근하려고 할 때 접근의 타이밍이나 순서에 따라 결과가 달라질 수 있는 상황을 의미한다.

동기화 (Synchronization)
경쟁조건 상황에 데이터 일관성을 지킬 수 있도록 제공하는 방법.

 

 

동기화 (Synchronization)

동기화 과정에 경쟁조건이 발생할 수 있는 동기화가 필요한 코드 영역을 임계영역(Critical Section) 이라고 하는데, 일반적으로 동기화는 이러한 임계영역에 데이터 일관성을 지키기 위해 락(Lock) 을 사용한다. 락(Lock)은 프로세스나 스레드가 임계영역에 접근할 수 있도록 하는 권한으로데이터 일관성 유지를 돕는다.

 

 

 

 

스핀락 ( Spinlock )

임계영역에 접근하기 위해서는 락(Lock)이 필요한데 락을 획득 하는 다양한 방법이 있을 수 있다.

줄을 서 한 명씩 요청하는 방법이 있을 수 있고 반면에 계속해서 임계영역에 접근해도 되는지 요청하는 작업을 반복할 수도 있다. 이와 같이 계속해서 임계영역에 접근해도 괜찮은지 물어보며 락을 획득하는 방식을 스핀락(Spinlock) 이라고 한다.

 

 

이러한 스핀락은 락을 획득 할 때 까지 반복해서 요청하는 Busy-Wating 방법을 제공하기 때문에 CPU의 많은 리소스 낭비로 이어질 수 있다는 단점을 가진다. 이와 같은 방법의 대안으로 뮤텍스(Mutex)가 있다.

 

뮤텍스 (Mutex)

Busy-Wating 방식의 리소스 낭비를 해결하기 위한 뮤텍스(Mutex)역시 임계영역에 접근하기 위해 락(Lock)을 필요로 한다. 다만 스핀락(Spinlock) 과의 차이는 대기 큐 ( Queue )를 제공하고 임계 영역에 접근하기 위한 스레드 혹은 프로세스를 줄 세워 대기시키는 방법이다. 이들은 대기 상태에 있다 락을 순서에 맞게 제공받아 임계영역에 접근하여 리소스 낭비를 최소화 한다.

하지만, 이러한 뮤텍스 방식이 언제나 스핀락 보다 효율이 좋은 것은 아니다.

 

스핀락이 뮤텍스보다 좋은 효율을 보일 때
  1. 멀티코어 환경으로 작업과 요청이 동시 처리 가능하여 계속된 요청에도 CPU의 시간 자원을 낭비할 필요가 없을 때.
  2. 임계영역 내 작업 시간이 빨리 끝나 대기시키는 작업이 필요하지 않을 때

 

 

 

세마포어 (Semaphore)

세마포어(Semaphore)는 깃발을 의미한다. 과거 공유되는 선로에서 지나가도 괜찮은지 깃발을 통해 기차에게 알려주었던 것에서 유래했다. 파란색이 걸려있으면 지나가도 괜찮지만 빨간색이 걸려있다면 다른 기차가 우선적으로 먼저 지나간 이후에 지나가야 한다는 것을 의미한다. 이러한 세마포어는 공유 데이터의 개수에 따라 바이너리(Binary) 와 카운팅(Counting) 방식으로 나뉜다.

 

바이너리 세마포어 (Binary Semaphore)

바이너리 세마포어는 공유 데이터 개수가 1개 인 것을 의미한다. 0 혹은 1의 값을 가질 수 있어 임계영역에 단 하나의 스레드만 접근할 수 있다. 임계영역 내 공유 데이터가 하나이기 때문에 하나의 스레드만 접근 가능한 것이다. 뮤텍스와 유사해 보이지만 Priority Inheritance 특성을 가진다는 차이가 있다.

카운팅 세마포어 (Counting Semaphore)

카운팅 세마포어는 공유 데이터의 개수가 N개 인 것을 의미한다. 임계 영역에 접근했을 때와 벗어날 때 각각 wait() signal() 을 외치는 것으로 접근 수를 카운팅해 동시 접근하는 스레드 혹은 프로세스의 수를 제한한다. 바이너리 세마포어와 다른 점은 동시에 여러 작업자가 임계영역에 접근할 수 있다는 점이다.

뮤텍스와 세마포어의 차이

뮤텍스는 락을 가진 작업자만 그 락을 해제할 수 있지만 세마포어는 임계영역에 접근하는 작업자가 다 수 일 수 있기 때문에 wait 과 signal 요청을 통해 스레드간 접근 순서를 결정 할 수 있다. 때문에 Priority Inheritance 라는 속성을 가진다. 마치 먼저 지나가야 하는 기차를 위해 빨간 깃발을 올려 다른 기차를 멈추게 하는 것과 같다.

 

뮤텍스는 보통 스레드간에 세마포어는 프로세스간에 주로 사용된다.

 

 

참조

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

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

https://jhnyang.tistory.com/101

댓글