Skip to content

Latest commit

 

History

History
162 lines (109 loc) · 8.66 KB

뮤텍스와 세마포어.md

File metadata and controls

162 lines (109 loc) · 8.66 KB

동기화 도구

공유 자원을 병행 접근하면 임계 구역(Critical Section) 에서 경쟁 상황(Race Condition) 이 발생하고 자료의 불일치를 초래할 수 있다.

이를 해결하기 위해 데이터를 한 번에 하나의 프로세스만 접근할 수 있도록 제한을 두는 동기화 방식을 취해야 한다.

동기화 도구에는 대표적으로 뮤텍스(Mutex)와 세마포어(Semaphore)가 있다.

이들은 모두 공유된 자원의 데이터를 여러 스레드/프로세스가 접근하는 것을 막는 역할을 한다.

경쟁 상황?

여러 개의 프로세스가 동일한 자료를 접근하여 조작하고, 그 실행 결과가 접근이 발생한 특정 순서에 의존하는 상황

경쟁 상태로부터 보호하기 위해 한 순간에 하나의 프로세스만이 공유 자료를 조작하도록 프로세스틀을 동기화 시켜야 한다.

임계 구역?

공유 자원에 접근하는 코드 영역(블록)을 임계 구역이라 부른다.

이 영역은 여러 프로세스나 스레드가 동시에 접근할 수 있으며, 이로 인해 경쟁 상황(Race Condition)이 발생할 수 있다.

do{
    // 진입 구역(진입 허가 요청)
        // 임계구역
    // 퇴출 구역
        // 나머지 구역
}while(true)

뮤텍스

뮤텍스 락(Mutex Lock) 또는 뮤텍스 세마포어(Mutex Semaphore)라고도 불린다.

공유된 자원의 데이터 혹은 임계영역(Critical Section) 등에 하나의 Process 혹은 Thread가 접근하는 것을 막아줌 (동기화 대상이 하나)

특정한 뮤텍스를 얻은 스레드만이 해당 뮤텍스를 해제할 수 있고, 다른 스레드나 프로세스는 뮤텍스의 상태를 직접 확인하거나 변경할 수 없다.

이러한 특성은 뮤텍스를 사용한 임계 구역의 상호 배제를 보장한다.

image1

뮤텍스의 연산

  1. 뮤텍스 락 (Mutex Lock): 사용자(스레드나 프로세스)는 락을 획득한다. 락을 획득한 사용자만이 임계 구역에 접근할 수 있다. 다른 사용자는 해당 락을 얻을 때까지 대기.

  2. 뮤텍스 언락 (Mutex Unlock): 락을 해제. 이로써 다른 사용자가 뮤텍스 락을 얻을 수 있게 된다.

뮤텍스가 사용되는 임계 구역은 공유가 불가능한 자원이기 때문에 하나의 뮤텍스 객체를 두 스레드가 동시에 사용할 수 없다.

acquire(){
    while(!available){
        ; /* busy wait. 바쁜 대기(스핀락) */
    }
    available = false;
}

release(){
    available = true;
}

do{
    acquire(); // 진입 구역(진입 허가 요청)
        // 임계구역
    release(); // 퇴출 구역
        // 나머지 구역
}while(true)

세마포어

프로세스를 동기화 시키는 (뮤텍스 락 보다) 좀 더 복잡한 동기화 도구

공유된 자원의 데이터 혹은 임계영역(Critical Section) 등에 여러 Process 혹은 Thread가 접근하는 것을 막아줌 (동기화 대상이 하나 이상)

사용하고 있는 스레드/프로세스의 수를 공통으로 관리하는 정수(=세마포어)를 이용해 상호 배제를 달성한다.

공유 자원에 접근할 수 있는 프로세스의 최대 허용치만큼 동시에 접근할 수 있으며, 각 프로세스는 세마포어의 값을 확인하고 변경할 수 있다.

image2

세마포어 종류

  1. 카운팅 세마포어: 양의 정수 값을 가지며 주로 공유 자원에 대한 동시 액세스를 제어하거나 스레드/프로세스 간의 작업 조율을 위해 사용
  2. 이진 세마포어: 0 또는 1의 두 가지 상태만 가지며, 주로 상호 배제 또는 임계 구역의 동시 접근을 제어하는 데 사용 -> 뮤텍스와 동일

즉, 세마포어는 뮤텍스가 될 수 있다.

세마포어의 연산

세마포어는 정수 변수로서, 두 가지 주요 연산을 지원한다.

  1. 세마포어 생성 (Semaphore Initialization): 세마포어는 초기값을 가짐. 이 초기값은 동시에 리소스에 접근할 수 있는 사용자(스레드/프로세스) 수를 나타냄

  2. 세마포어 연산 (Semaphore Operations): 세마포어는 다음 두 가지 주요 연산을 지원한다.

    • P 연산 (Wait): 사용자가 세마포어를 얻으려고 시도. 만약 세마포어 값이 0보다 큰 경우, 사용자는 세마포어를 얻고, 값은 감소된다. 값이 0인 경우 사용자는 대기 상태로 들어간다.
    • V 연산 (Signal): 세마포어를 해제하고 다른 사용자가 세마포어를 사용할 수 있게 하고 값은 증가된다. 대기 중인 사용자 중 하나가 세마포어를 얻게 됨.
wait(S){
    while(S<=0){
        ; /* busy wait. 바쁜 대기(스핀락) */
    }
    S--;
}

signal(S){
    S++;
}

do{
    wait(S); // 진입 구역(진입 허가 요청)
        // 임계구역
    signal(S); // 퇴출 구역
        // 나머지 구역
}while(true)

뮤텍스와 세마포어의 차이

동기화에 관한 유명한 예제 중 하나인 Toilet problem을 통해 둘의 차이점을 알아보자!

뮤텍스

뮤텍스는 화장실이 하나 뿐이 없는 식당과 비슷하다. 화장실을 가기 위해서는 카운터에서 열쇠를 받아 가야 한다.

화장실의 상태를 직접 확인할 수는 없으며, 카운터에 키가 있으면 화장실에 사람이 없다는 뜻이고 당신은 그 열쇠를 이용해 화장실에 들어갈 수 있다.

image3

화장실을 이용하는 사람은 프로세스 혹은 스레드 이며 화장실은 공유자원, 화장실 키는 공유자원에 접근하기 위해 필요한 어떤 오브젝트이다.

즉, 뮤텍스는 Key에 해당하는 어떤 오브젝트가 있으며 이 오브젝트를 소유한 프로세스/스레드 만이 공유자원에 접근할 수 있다.

세마포어

세마포어는 손님이 화장실을 좀 더 쉽게 이용할 수 있는 레스토랑이다.

세마포어를 이용하는 레스토랑의 화장실에는 여러 개의 칸이 있다. 그리고 화장실 입구에는 현재 화장실의 빈 칸 개수를 보여주는 전광판이 있다.

만약 화장실에 가고 싶다면 입구에서 빈 칸의 개수를 확인하고 빈 칸이 1개 이상이라면 빈칸의 개수를 하나 뺀 다음에 화장실로 입장해야 한다.

그리고 나올 때 빈 칸의 개수를 하나 더해준다.

image4

모든 칸에 사람이 들어 갔을 경우 빈 칸의 개수는 0이 되며 이때 화장실에 들어가고자 하는 사람이 있다면 빈 칸의 개수가 1 혹은 양수로 바뀔 때까지 기다려야 한다.

image5

세마포어도 아까와 똑같이 화장실이 공유자원이며 사람들이 프로세스/스레드이다. 그리고 화장실 빈칸의 개수는 현재 공유자원에 접근할 수 있는 프로세스/스레드의 개수를 나타낸다.

이처럼 세마포어는 공통으로 관리하는 하나의 값을 이용해 상호 배제를 달성한다.

총정리

  • 뮤텍스는 동기화 대상이 오직 1개일 때 사용하며, 세마포어는 동기화 대상이 1개 이상일 때 사용한다. (-> 화장실의 개수)
  • 뮤텍스는 자원을 소유할 수 있고 소유주만이 해제할 수 있는 반면 세마포어는 자원 소유가 불가하다. (->화장실 키 여부)
  • 세마포어는 시스템 범위에 걸쳐 있고, 파일 시스템 상의 파일로 존재한다. 반면, 뮤텍스는 프로세스의 범위를 가지며 프로세스 종료될 때 자동으로 Clean up 됩니다.
  • 세마포어는 뮤텍스가 될 수 있지만, 뮤텍스는 세마포어가 될 수 없다.

뮤텍스와 세마포어는 모두 완벽한 기법은 아니므로 데이터 무결성을 보장할 수는 없으며, 모든 교착상태를 해결하지는 못한다.

하지만 상호배제를 위한 기본적인 문법이며 여기에 좀 더 복잡한 매커니즘을 적용해 개선된 성능을 가질 수 있도록 하는 것이 중요하다.


Reference

뮤텍스(Mutex)와 세마포어(Semaphore)의 차이

[운영체제] Mutex 뮤텍스와 Semaphore 세마포어의 차이

[OS] 뮤텍스(Mutex)와 세마포어(Semaphore)란?