Mutex Lock과 Semaphore

정호윤·2024년 2월 22일
0

동기화

목록 보기
2/4

동기화란 여러 프로세스가 공유 자원에 접근할 때 발생하는 문제를 해결하기 위한 기법입니다. 참고로 모든 동기화 관련된 내용은 프로세스뿐만 아니라 쓰레드에도 적용됩니다. 동기화는 크게 두 가지 종류가 있습니다.

  1. 상호 배제(Mutual exclusion)를 위한 동기화
  2. 실행 순서 제어를 위한 동기화

상호 배제를 위한 동기화를 통해 여러 프로세스가 동시에 공유 자원에 접근하는 것을 막을 수 있습니다. 실행 순서 제어를 위한 동기화는 특정 작업이 다른 작업이 끝나기를 기다려야 할 때 사용합니다. 이제 동기화를 달성하기 위한 대표적인 기법들을 살펴봅시다.


Mutex Lock

Mutex lock은 상호 배제를 위한 동기화를 지원하지만, 실행 순서 제어를 위한 동기화는 보장하지 않습니다. Mutex lock은 하나의 공유 자원에 대한 접근을 제한합니다. Lock을 획득(acquire)한 프로세스는 critical section에 진입할 수 있습니다. Critical section을 모두 실행하고 나면, 프로세스는 lock을 반환(release)합니다.

lock.lock()    // Lock 획득
// Critical section
lock.unlock()  // Lock 해제

Mutex lock은 크게 busy waiting 방식과 sleep-and-wakeup 방식으로 구현할 수 있습니다. Busy waiting 방식은 프로세스가 lock을 획득할 때까지 무한 루프를 돌면서 기다립니다. Sleep-and-wakeup 방식은 프로세스가 lock을 획득할 수 없다면 대기 큐에 들어가고, 다른 프로세스가 lock을 반환하며 깨워줄 때까지 sleep하는 방식입니다.

싱글 코어 환경에서의 busy waiting은 sleep-and-wakeup 방식에 비해 일반적으로 좋지 않은 성능을 보여줍니다. 반면에 멀티코어 환경에서는 상황에 따라 busy waiting 방식이 더 좋은 성능을 보이기도 합니다. 만약 busy waiting 시간이 context switch를 하는 데 걸리는 시간보다 짧은 경우, 더 좋은 성능을 보이기도 합니다.


Semaphore

세마포어(Semaphore)는 상호 배제실행 순서 제어를 위한 동기화를 지원합니다. 세마포어는 mutex lock과는 달리, 여러 공유 자원에 대한 접근을 제한합니다. 즉, 세마포어는 공유 자원이 여러 개일 때 사용할 수 있는 동기화 기법입니다. 세마포어는 동시에 접근 가능한 공유 자원의 개수에 따라 이진 세마포어카운팅 세마포어로 나뉘며, 각각은 mutex lock과 마찬가지로 busy waiting이나 sleep-and-wakeup 방식으로 구현될 수 있습니다.

  • 이진 세마포어: 한 개의 공유 자원에 대한 접근을 제한 (Mutex lock과 유사)
  • 카운팅 세마포어: 여러 개의 공유 자원에 대한 접근을 제한

세마포어는 wait 함수를 사용해 lock 획득을 시도하고, signal 함수를 사용해 lock을 반환합니다. 또한 세마포어에서의 lock 획득과 반환이 mutex lock과 다른 점은, 단일 쓰레드에서 수행되지 않아도 괜찮다는 점입니다. 따라서 세마포어는 waitsignal을 적절히 사용해 실행 순서를 제어할 수 있습니다.

다음은 세마포어를 사용해 실행 순서를 제어하는 예시입니다. 세마포어 값을 0으로 설정한 상태라면, 두 쓰레드가 실행되는 시점에 관계없이 항상 쓰레드 A가 먼저 실행됩니다.

쓰레드 B는 critical section에 진입하기 전에 wait를 호출하지만 세마포어 값이 0이므로 lock을 획득할 수 없습니다. 따라서 쓰레드 B는 쓰레드 A의 signal이 호출되어 세마포어 값이 1이되기 전까지 실행될 수 없습니다. 쓰레드 B는 구현 방식에 따라 busy waiting을 하거나 sleep-and-wakeup 방식으로 lock 획득을 기다립니다.


출처

0개의 댓글

관련 채용 정보