Post

CS - 뮤텍스와 세마포어

들어가며

이번 포스트에서는 뮤텍스와 세마포어에 대해 이해해 보겠습니다.

프로세스 혹은 스레드가 동시에 같은 공유 자원에 접근할 때 문제가 생기지 않도록 하는 방법이 필요한데요. 이때 동기화 방식으로 접근해볼 수 있습니다.

뮤텍스와 세마포어는 동기화 도구 입니다. 하나의 방법 정도로 이해하면 됩니다.

먼저 이해할 용어

공유자원

공유자원은 말그대로 공유하는 자원입니다. 예를 들어 2개의 프로세스가 동시에 접근하는 메모리가 있다면 공유 메모리 라고 하며 이것이 공유 자원입니다. OS 에서는 메모리를 하드웨어 자원이라면 파일을 DB에서도 공유하는 자원이 있을 수 있습니다. 이런 작업들을 효율적으로 처리하기 위한 방법입니다.

경쟁상태

두개 이상의 프로세스가 동시에 공유 자원에 접근하여 의도와 다른 결과를 가지고 오는 것을 말하는데 대표적으로 은행원알고리즘에서 해결하는 동일한 시간에 은행계좌에 접근해 돈을 입금하고 출금하는 동안 의도치 않은 결과를 가지고 와서 옳바른 값이 저장 되지 않는 경우가 있습니다.

임계영역

공유 자원에 접근하는 순서에 따라 결과가 달라질 수 있는 코드 영역을 의미합니다.

임계 영역에서 실행되는 코드는 다른 프로세스의 방해를 받지 않도록 해야 합니다.

즉, 한 프로세스가 임계 영역에 진입하면 다른 프로세스는 그 영역에 들어갈 수 없어야 합니다.

예를 들어 변기가 공유자원이라면 임계영역은 화장실 같은 것이죠

Mutex

뮤텍스는 한 번에 하나의 프로세스만 임계 영역에 진입하도록 하는 메커니즘입니다

뮤텍스 객체는 잠금 및 해제 메서드를 제공하며, 임계 영역에 진입하려는 프로세스는 먼저 뮤텍스를 잠가야 합니다.

뮤텍스가 잠겨있는 경우 다른 프로세스는 대기 상태에 들어가 뮤텍스가 해제될 때까지 기다려야 합니다.

뮤텍스는 Key를 기반으로 한 상호배제 기법입니다. 키를 가진 어떤 객체가 있고 이를 소유한 프로세스 , 스레드가 이 공유 자원에 접근할 수 있도록 하는 방법입니다.

Semaphore

세마포어는 뮤텍스와 유사하지만, 동시에 임계 영역에 진입할 수 있는 프로세스의 수를 제한하는 데 사용할 수 있습니다.

세마포어 객체는 카운터와 연산 메서드를 제공하며, 임계 영역에 진입하려는 프로세스는 카운터를 감소시켜야 합니다.

카운터 값이 0이면 임계 영역이 사용 중이며, 프로세스는 대기 상태에 들어가 카운터 값이 1 이상이 될 때까지 기다려야 합니다.

여러개의 프로세스 , 스레드가 접근할 수 있고 , 이것을 연산하는 카운터가 존재하여서 0이면 못들어가고 양수값이 될때만 사용할 수 있도록 하는 기법입니다.

차이점

정리하면 뮤텍스는 하나 , 세마포어는 여러개의 동기화 대상을 가집니다.

결국 뮤텍스는 키를 통해 자원을 소유한다는 개념에서 시작하는 것이고 , 반대로 세마포어는 자원을 소유하지는 않습니다.

쉽게 생각해서 뮤텍스는 boolean 형과 유사하고 세마포어는 array에 카운터를 세서 접근 가능여부를 확인 시켜주는 기법이라고 생각하면 됩니다.

추가 - 모니터

모니터 라는 기법도 존재합니다. 모니터는 공유 변수와 프로세스 간의 동기화를 위한 고급 동기화 메커니즘입니다. 모니터는 조건 변수와 같은 추가 기능을 제공하며, 복잡한 동기화 문제를 해결하는 데 유용합니다.

모니터의 구성 요소

모니터는 다음과 같은 세 가지 주요 구성 요소로 구성됩니다.

  1. 공유 변수: 모니터 내부에 선언되는 변수로, 여러 프로세스가 동시에 접근하고 변경할 수 있습니다.
  2. 조건 변수: 프로세스가 특정 조건을 만족할 때까지 대기하도록 하는 메커니즘입니다.
  3. 진입 절차: 프로세스가 모니터에 진입하고 공유 변수에 접근하기 위한 규칙을 정의합니다.

모니터의 동작 방식

모니터는 다음과 같은 방식으로 동작합니다.

  1. 프로세스가 모니터에 진입하기 위해서는 wait() 연산을 수행해야 합니다. wait() 연산은 조건 변수와 함께 사용될 수 있으며, 조건이 충족되지 않을 경우 프로세스는 대기 상태에 들어갑니다.
  2. 대기 상태에 있는 프로세스는 signal() 또는 broadcast() 연산을 통해 다른 프로세스에 의해 다시 활성화될 수 있습니다. signal() 연산은 대기 상태에 있는 프로세스 중 하나를 선택하여 활성화하는 반면, broadcast() 연산은 모든 대기 상태에 있는 프로세스를 활성화합니다.
  3. 프로세스가 모니터를 떠나기 전에 signal() 또는 broadcast() 연산을 수행하여 다른 프로세스가 진입하도록 해야 합니다.
This post is licensed under CC BY 4.0 by the author.