2 minute read

뮤텍스 락

  • 상호 배제를 위한 동기화 도구 (자물쇠 역할)
  • 전역 변수 하나, 함수 두개
    • lock : 자물쇠 역할의 전역 변수
    • acquire : 임계 구역을 잠그는 함수
    • release : 임계 구역의 잠금을 해제하는 함수
void acquire()
{
    while (lock == true)
        ;                   /* 임계 구역이 잠겨 있는지를 잠겨 있지 않을 때까지, 반복 확인 */

    lock = true;            /* 임계 구역이 잠겨 있지 않다면, 임계 구역을 잠금*/
}

void release()
{
    lock = false;           /* 임계 구역 작업이 끝난 후 잠금 해제*/
}

void SomeThread()
{
    acquire();             /* 자물쇠가 잠겨있는지 확인 후, 자물쇠가 풀릴 때까지 기다렸다가 자물쇠를 잠그고 들어옴 */
    // 임계 구역
    release();             /* 자물쇠를 풂 */
}

바쁜 대기

    while (lock == true)    /* 만약 임계 구역이 잠겨 있다면 */
    ;                       /* 임계 구역이 잠겨 있는지를 반복적으로 확인 */

문이 잠겨있는지를 계속 덜컹거리며 확인 (CPU 자원 계속 소모)

세마포

  • 좀 더 일반화된 방식의 동기화 도구
  • 공유 자원이 여러 개 있는 경우에도 적용 가능
  • 여기에선 카운팅 세마포를 지칭 (이진 세마포는 뮤텍스 락과 유사)
  • 세마포의 단순한 형태 : 전역 변수 하나, 함수 두 개
    • S : 임계 구역에 진입할 수 있는 프로세스 개수를 나타내는 전역 변수
    • wait : 임계 구역에 들어가도 좋은지, 기다려야 할지를 알려주는 함수
    • signal : 임계 구역 앞에서 기다리는 프로세스에게 ‘이제 가도 좋다’고 신호를 주는 함수 ```c++ void SomeThread() { wait(); // 임계 구역 signal(); }

void wait() { while ( S <= 0) ; S–; } void signal() { S++; }

## 바쁜 대기 해결 방법
* 사용할 수 있는 자원이 없을 경우 `대기 상태`로 만듦
(해당 프로세스의 PCB를 대기 큐에 삽입)
* 사용할 수 있는 자원이 생겼을 경우, 대기 큐의 프로세스를 `준비 상태`로 만듦
(해당 프로세스의 PCB를 대기 큐에서 꺼내 준비 큐에 삽입)

## 실행 순서 제어 동기화
```c++
int S = 0;

void P1() // 먼저 실행 되어야 함
{
    // 임계 구역
    signal();
}

void P2() // 나중에 실행 되어야 함
{
    wait();
    // 임계 구역
}

모니터

뮤텍스 락, 세마포 같은 경우는 앞뒤로 함수를 붙여줘야 해서 실수가 발생할 수 있고, 실수로 누락하거나 순서를 헷갈리거나, 중복해서 같은 함수를 붙일 시 디버깅이 어렵다.
모니터 : 사용자가 사용하기 편한 동기화 도구

상호 배제를 위한 동기화

  • 인터페이스를 위한 큐
  • 공유 자원에 접근하고자 하는 프로세스를 (공유 자원을 위한) 큐에 삽입
  • 큐에 삽입된 순서대로 (한 번에 하나의 프로세스만) 공유 자원 이용

    실행 순서 제어를 위한 동기화

  • 조건 변수(Condition Variable)를 이용
  • 프로세스나 스레드의 실행 순서를 제어하기 위해 사용하는 특별한 변수
    • 조건 변수.wait() : 대기 상태로 변경, 조건 변수에 대한 큐에 삽입
    • 조건 변수.signal() : wait()로 대기 상태가 된 프로세스를 준비 상태로 변경