본문 바로가기
cs공부/운영체제

운영체제 - Semaphore(세마포어), Mutex(뮤텍스)

by 코딩하는 돼징 2023. 5. 23.
반응형

Mutex

여러 쓰레드가 공유 자원에 접근하는 것을 제어하기 위해 사용된다. 커널 동기화 객체이다. 오직 한 번에 하나의 프로세스 또는 쓰레드만이 임계구역에 진입할 수 있도록 한다.


01 WaitOne

Mutex에 대한 접근을 시도하고 허용될때까지 대기한다.

public virtual bool WaitOne ();

02 ReleaseMutex

Mutex를 한번 해제한다.

public void ReleaseMutex ();

Code 예시

static Mutex mutex = new Mutex();

static void Main(string[] args)
{
    for (int i = 0; i < 5; i++)
    {
        Thread thread = new Thread(MutexExample);
        thread.Name = String.Concat("Thread", i);
        thread.Start();
    }
}

private static void MutexExample()
{
    // Mutex에 진입
    mutex.WaitOne();
    Console.WriteLine("{0} Enters", Thread.CurrentThread.Name);

    Thread.Sleep(100);

    Console.WriteLine("{0} Exits", Thread.CurrentThread.Name);

    // Mutex에서 나감
    mutex.ReleaseMutex();
}


1. S/W적 구현

Peterson's Solution, Bakery 알고리즘

 

운영체제 - Peterson's Solution, Bakery 알고리즘(상호배제 문제 해결)

임계구역에 대한 요구사항 01 상호 배제(mutal exclusion) 한 프로세스가 임계 구역을 실행 중일때, 다른 어떤 프로세스도 임계 구역을 실행할 수 없다. 02 진행(Process) 임계구역 안에 반드시 하나의 프

code-piggy.tistory.com



2. H/W적 구현

하드웨어적인 mutex는 프로세서 레벨에서 지원되는 원자적 연산을 활용하여 구현한다.

01 Test-and-Set

lock에 대한 test 혹은 copy를 CPU의 명령어로 제공한다. CPU명령어 하나는 문맥교환없이 원소적으로 수행된다.

특정 변수를 Test해서 그 값이 원하는 값이면 새로운 값으로 바꿔주는 식으로 작동한다.

프로세스가 임계구역을 빠져나가면서 lock을 0으로 바꾸면 mutex가 해제되면서 대기하고 있던 프로세스 중 가장 먼저 test_and_set을 수행시킨 딱 하나의 프로세스가 딱 한번만 0의 값을 리턴 받게 되면 mutext를 해제하면서 임계구역에 접근하여 작업을 수행할 수 있게된다.

static int TestAndSet(ref int target)
{
    int oldValue = Interlocked.Exchange(ref target, 1); 
    return oldValue; // 이전 값을 반환
}

target - 임계구역의 상태

반환값이 0인 경우 : 이전 값이 0이면 target 변수를 성공적으로 1로 설정하여 임계구역에 진입한다.

반환값이 1인 경우 : 이전 값이 1이면 target 변수가 이미 다른 프로세스에 의해 잠겨있어 임계구역에 진입할 수 없다.


02 Compare-and-Swap

변수의 현재 값과 기대하는 값을 비교하여 동일한 경우에만 새로운 값을 설정함에 따라 

Interlocked.CompareExchange(ref target, newValue, expected)

target과 expected 값을 비교하고 같다면 target에 newValue를 대입, 다르다면 다른 쓰레드가 target변수를 변경한 것이므로 전의 값을 유지한다.


 

03 Interrupt-disable

인터럽트를 일시적으로 비활성한다, 특권 명령어이기 때문에 사용자 모드에서는 사용 불가능하다.

커널 내의 시스템 호출 부분과 인터럽트 처리기의 임계 구역 보호를 위해 사용한다.

04 Interrupt-enable

인터럽트를 다시 활성화 한다. 특권 명령어이기 때문에 사용자 모드에서는 사용 불가능하다.

커널 내의 시스템 호출 부분과 인터럽트 처리기의 임계 구역 보호를 위해 사용한다.


Busy Waiting

 

SW구현과 HW구현 모두 "busy waiting" 알고리즘이다.

임계구역 진입 시 이미 다른 프로세스가 진입해 있으며 busy-waiting loop(while, do-while등) 실행하게 되면서 타임슬라이가 낭비 된다.


Semaphore

커널 동기화 객체이다.여러 프로세스 또는 쓰레드 간의 상호작용을 조정하는데 사용된다. 진입 불가능시에는 대기 상태로 변환하고 임계 구역을 떠나는 프로세스가 대기 프로세스를 준비 상태로 깨워준다

세마포어는 일종의 객체로 구성되며, 하나의 정수값(사실은 정수변수 value)을 통해서 자원의 활용 현황을 나타낸다.


세마포어 연산에는 세 가지가 있다.

01 init 

세마포어의 초기값을 설정

public Semaphore (int initialCount, int maximumCount);

매개변수

initialCount : 세마포어에 동시에 부여할 수 있는 초기 요청 수

maximumCount : 세마포어에 부여할 수 있는 최대 요청


2. wait 또는 P연산

자원을 획득하기 위해 대기하며, 세머 포어 값이 감소한다. 세머포어 값이 음수가 되면 대기 상태로 전환된다.

public virtual bool WaitOne ();

현재쓰레드를 블록하고 세마포어가 신호를 받을때까지 기다린다. 세마포어가 사용가능한 상태가 되면 쓰레드는 세마포어를 획득하고 작업을 계속할 수 있다.

반환 값이 false이면 세마포어를 획득하지 못한 것이고 true이면 획득한 것이다.


3. signal 또는 V연산

자원을 반납하고 대기 중인 프로세스를 깨우면서 세머포어 값이 증가한다.

public int Release (int releaseCount);

releaseCount : 자원을 반납할 수(세마포어가 그만큼 값이 증가된다)

Release()메서드를 통해서 자원을 반납하고 대기 중인 프로세스를 깨우면서 세마포어 값이 증가한다.

매개변수


Semaphore 객체를 S라 할때 S.value : 자원 활용 현황이다.

양수 : 남아있는 자원 수

음수 : 부족하여 대기하고 있는 대기자 수


Code 예시

static Semaphore semaphore = new Semaphore(3, 3); 

static void Main(string[] args)
{
    for(int i = 0; i< 5; i++)
    {
        Thread thread = new Thread(SemaphoreExample);
        thread.Name = String.Concat("Thread", i);
        thread.Start();
    }
}
private static void SemaphoreExample()
{
    // 세마포어에 진입
    semaphore.WaitOne();
    Console.WriteLine("{0} Enters", Thread.CurrentThread.Name);
     
    Thread.Sleep(100);

    Console.WriteLine("{0} Exits", Thread.CurrentThread.Name);

    //세마포어에서 나감
    semaphore.Release();
}

과정

1. 초기 요청 수를 3으로 해놓았으므로 초기 상태에서 세마포어의 count값은 3이다.

2. Thread0, Thread1, Thread2, Thread3, Thread4는 각각 SemaphoreExample에서 semaphore.WaitOne()을 호출하여 세마포어에 진입을 대기한다.

3. 초기값이 3이므로 3개의 쓰레드가 세마포어를 획득하고 진입한다.

4. 각각의 작업을 수행하고 Release()호출을 통해 세마포어를 반납하고 다른 쓰레드가 진입할 수 있도록한다.


Semaphore와 Mutex차이점

Semaphore : 공유 자원에 대한 접근을 제어하는데 사용된다. 동시에 여러 개의 프로세스 또는 쓰레드가 임계구역에 진입할 수 있도록 한다.

Mutex :  공유 자원의 상호 배제를 위해 사용된다. 오직 한 번에 하나의 프로세스 또는 쓰레드만이 임계구역에 진입할 수 있도록 한다.

 

 

 

 

반응형

댓글