Process / Thread Synchronization 기법

라마·2023년 7월 24일

운영체제

목록 보기
21/32

※ 전남대학교 박태준 교수님의 운영체제 강의를 듣고, 정리한 내용입니다.

동기화 정리

Lock 방식 : 뮤텍스 ( mutex ) , 스핀락 ( spinlock )

  • 상호배제가 되도록 만들어진 락 ( lock ) 활용

  • 동기화 대상이 1개일 때 사용

  • 락을 소유한 쓰레드만이 임계구역에 진입할 수 있음

  • 락을 소유하지 않은 쓰레드는 락이 풀릴 때 까지 밖에서 대기

뮤텍스와 스핀락의 차이는, busy-wait 이냐 sleep-wait 이냐에 따라 달라지게 됩니다.

wait - signal 방식 : 세마포어 ( semaphore )

  • N 개의 자원을 사용하려는 M 개의 멀티쓰레드의 원활한 관리

    • 카운터를 활용함
  • 자원을 소유하지 못한 쓰레드는 대기 ( wait )

  • 자원을 다 사용한 쓰레드는 알림 ( signal )

Mutex ( Mutual Exclusion )

잠김 / 열림 중 한 상태를 가지는 락 변수를 이용하여 한 쓰레드만 임계구역에 진입시키고 다른 쓰레드는 대기 큐에 대기하도록 합니다.

그리고 lock 연산 후 락이 잠겨있을 경우, 다시 대기 큐로 돌아가는 sleep-waiting lock 기법을 사용합니다.

구성 요소

  1. lock 변수

    1. true / false 중 한 값

    2. true : 락을 잠근다 ( 락을 소유한다 )

    3. false : 락을 연다 ( 락을 해제한다 )

  2. 대기 큐

    1. 락이 열리기를 기다리는 쓰레드 큐
  3. 연산

    1. lock 연산 ( 임계구역의 entry 코드 )

      1. 락이 잠김 상태일 경우, 현재 쓰레드를 Block 상태로 만들고 대기 큐에 삽입

      2. 락이 열린 상태일 경우, 락을 잠그고 임계구역 진입

    2. unlock 연산 ( 임계구역의 exit 코드 )

      1. lock 이 잠김 상태일 경우, lock 을 열린 상태로 변경

      2. 대기 큐에서 기다리는 쓰레드를 하나 깨움

Spinlock

뮤텍스의 non-blocking 모델 ( busy - waiting ) 을 spinlock 이라고 부릅니다.

spinlock 의 경우 락이 잠겨 있을 때 block 되지 않고 ( 대기 큐로 돌아가지 않고 ) 락이 풀릴 때 까지 검사 코드를 실행합니다.

  • 큐가 아닌 while loop 로 대기함

단일 CPU ( 단일 코어 ) 를 가진 운영체제에서 비효율적이고, 멀티 코어에 적합한 모델 입니다.

  • 단일 코어 CPU 의 경우, 의미 없는 CPU 시간 낭비

    • 왜냐하면 락이 풀릴 때 까지 검사 코드를 반복적으로 실행하니, 불필요한 CPU 연산이 요구되기 때문
  • 스핀락을 검사하는 쓰레드의 타임 슬라이스가 끝날 때 까지 다른 쓰레드 실행 X

  • 임계구역의 실행 시간이 짧은 경우 효과적

  • 기아 현상이 발생할 수 있음

세마포어 ( Semaphore )

세마포어는 N 개의 공유 자원을 다수의 쓰레드가 공유하여 사용하도록 돕는 자원 관리 기법입니다.

  • 동시에 여러 개의 프로세스 ( 혹은 쓰레드 ) 가 임계 구역에 접근할 수 있도록 카운터를 가지고 있는 입구

  • 일정 수가 넘어가버리면 들어가지 못함

구성 요소 ( Counter Semaphore )

  1. 자원 : N 개

  2. 대기 큐 : 자원을 할당받지 못한 쓰레드들이 대기하는 큐

  3. Counter 변수

    1. 사용 가능한 자원의 개수를 나타내는 정수형 전역 변수

    2. N 으로 초기화 ( Counter = N )

  4. P / V 연산

    1. P 연산 ( wait 연산 ) : 자원 요청 시 실행하는 연산

      1. 자원 사용 허가를 얻는 과정
    2. V 연산 ( signal 연산 ) : 자원 반환 시 실행하는 연산

      1. 자원 사용이 끝났음을 알리는 과정

P 연산과 V 연산

P/V 를 wait/signal 이라고 표기하기도 합니다.

  • P 연산 : 자원 사용을 허가하는 과정

    • 사용 가능 자원 수 1 감소 ( counter-- )
  • V 연산 : 자원 사용을 마치는 과정

    • 사용 가능 자원 수 1 증가 ( counter++ )
  • 세마포어의 종류 : 2가지

    • 자원을 할당받지 못한 경우의 행동에 따라 구분 ( busy-wait, sleep-wait )

세마포어를 통한 자원 관리 예제

4개의 인스턴스를 가진 자원에 대해, 4개의 쓰레드 ( T1 ~ T4 ) 가 할당 받아 사용중이고, 2개의 쓰레드 T5,T6 는 자원을 기다리고 있는 상태 입니다.

이 때 counter 변수는 사용 가능한 자원의 개수를 나타내며, 음수일 경우 대기 중인 쓰레드의 수를 나타내게 됩니다. ( P연산, counter = -2 )

할 일을 다 처리한 쓰레드는 V 연산을 진행하면서 자원을 반환하고 ( counter ++ ), 그 자리에 대기중인 쓰레드가 들어가게 됩니다.

이진 세마포어

  • 자원이 1개 있는 경우 멀티쓰레드 사이의 자원 관리

  • 1개의 자원에 대해 1개의 쓰레드만 액세스할 수 있도록 보호

  • 뮤텍스와 매우 유사함

뮤텍스와 세마포어의 차이점

  • 동기화 대상의 갯수

    • Mutex : 동기화 대상이 1개일 때 사용
    • Semaphore : 동기화 대상이 1개 이상일 때 사용
  • 세마포어는 뮤텍스가 될 수 있지만 ( 이진 세마포어 ) , 뮤텍스는 세마포어가 될 수 없음

  • 뮤텍스는 자원 소유 가능 + 책임을 가지는 반면, 세마포어는 자원 소유 불가

    • 뮤텍스는 자신이 Lock 변수를 가지고 문을 잠그기 때문에 자원을 소유하고, 책임을 가짐
    • 세마포어의 경우 n개의 자원에 접근하는 것이기 때문에, 특정 자원을 소유하는 것이 아님
    • 쉽게 생각하면 비어있는 아무 자원에 그냥 붙어서 일하고, 나가는 것이기 때문에 특정 자원 소유 불가능!
  • 뮤텍스는 소유하고 있는 쓰레드만이 현재 뮤텍스를 해제할 수 있음

    • 세마포어는 세마포어를 소유하지 않는 쓰레드가 세마포어를 해제할 수 있음
    • 세마포어의 경우 자신이 마지막으로 들어왔다고 하더라도, 중간에 다른 쓰레드가 나가버리면 문이 열리는 것이기 때문에 다른 쓰레드가 세마포어를 해제할 수 있음

세마포어의 자원 소유 불가능다른 쓰레드가 세마포어를 해제할 수 있음 의 간단한 예시를 들어보겠습니다.

현재 4개의 자원중 3개가 할당된 상태고, 1개가 비어있다고 가정해보겠습니다.

이 비어있던 자원에 T4 를 할당해주면, 자원을 다 쓰고있는 상태가 되니 나머지 쓰레드들은 대기 큐에서 기다리게 됩니다.

이때 다른 쓰레드가 작업을 다 마치고 자원을 반납하게 되면, 세마포어가 해제되고 ( 문이 열림 ) 대기중인 쓰레드들이 진입할 수 있게 됩니다.

즉 T4 가 마지막으로 문을 닫고 들어왔지만, T4 가 아닌 T1 에 의해 문이 열리게 됩니다.

  • 다른 쓰레드에 의해 문이 열림

그러므로 세마포어를 소유하지 않는 쓰레드가 세마포어를 해제할 수 있다고 볼 수 있습니다.

그리고 비어있는 자원에 붙어서 일하는 방식이기 때문에, 세마포어는 자원을 소유할 수 없다고도 볼 수 있습니다.

Monitor ( 모니터 )

  • 공유 자원을 내부적으로 숨기고 공유 자원에 접근하기 위한 인터페이스만 제공

  • 말 그대로 중간 단계를 하나 더 넣어준 것! → 추상화를 위해!

  • 자원 보호, 프로세스 간 동기화 O

  • 작동원리

    • 임계구역으로 지정된 자원에 접근하고자 하는 프로세스는 직접 P 나 V 를 사용하지 않고 모니터에 작업 요청
    • 모니터는 요청받은 작업을 모니터 큐에 저장한 후 순서대로 처리하고 그 결과만 해당 프로세스에 알려줌

0개의 댓글