# CHAPTER 3 운영체제 - 스핀락, 뮤텍스, 세마포

금성·2023년 1월 4일
0

CS 전공지식 노트

목록 보기
7/19

SECTION 3.4 - 스핀락, 뮤텍스, 세마포

그럼 이제 동기화를 위한 여러 전략과 각각의 차이를 알아보자

먼저, 앞에서 배운 개념을 잠깐 짚고 넘어가자.

경쟁 상태 ( Race Condition )

여러 프로세스/스레드가 동시에 같은 데이터를 조작할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황

동기화 ( Synchronization )

여러 프로세스/스레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것

임계 영역 ( Critical Section )

공유 데이터의 일관성을 보장하기 위해 하나의 프로세스/스레드만 진입해서 실행 가능한 영역

임계영역에서 이 하나의 프로세스/ 스레드만 진입해서 실행한다는 의미가 바로

Mutual exclusion

Mutual exclusion을 보장 하는 법

lock을 사용하면 됨

프로세스 / 스레드가 lock을 획득하기위해 경합을 하고 그 중 성공한 프로세스 /스레드가 임계영역에 들어가서 실행하고, 임계영역에서 자신이 할일을 마칠 경우 다시 lock을 반환

예를 들어보자
간단한 함수 설명

  • global로 lock을 사용 => 동시에 lock에 접근 가능, critical이라는 함수는 while 루프를 통해 lock을 획득하려고 시도 할것, 최종적으로는 lock을 반환

쓰레드 ( T1, T2 ) 가 존재한다고 하고 함수를 보자
1. T1이 먼저 시작하고 lock이 0이므로 임계영역안으로 들어와서 실행됨
2. T1이 임계영역에 들어오면서 lock이 1로 바뀜
3. 그리고 T2가 시작되고 lock이 1이기 때문에 임계영역안으로 진입할 수 없음
4. T1이 자기 할일을 마치고 lock을 반환하면서 0으로 바뀜
5. T2가 이제 lock 0값을 가지고 while 루프 탈출하고 임계영역안으로 진입
6. 위 과정이 반복

T1과 T2가 임계영역안에서 동시에 실행되지 못함을 확인

하지만 물론 T1과 T2가 동시에 test and set을 호출하고 동시에 lockPtr을 실행하게되면 동시에 임계영역으로 들어올 수 있지 않을까? 하고 생각할 수 있다.

test and set이라는 함수는 CPU의 도움을 받음

CPU의 atomic 명령어

  • 실행 중간에 간섭받거나 중단되지 않음
  • 같은 메모리 영역에 대해 동시에 실행되지 않음
    => 절대 동시에 실행될 수 없게함 ( test and set의 body는 그냥 예시임 )

그래서 우리가 우려했던 그런일은 일어나지 않음

while에서 lock 체킹

예제에서 while 루프를 빠져나갈때 까지 lock을 확인하면서 lock을 가질 수 있을 때 까지반복 됨 이를 스핀락이라고 함

1. 스핀락 ( Spinlock )

락을 가질 수 있을때 까지 반복해서 시도

하지만 이 방식은 lock을 기다리는 동안 CPU를 낭비한다는 단점 존재
ㅈ댐을 감지...

lock이 준비가 되면 자신을 깨워달라는 방식이 등장


2. 뮤텍스 ( Mutex )

lock을 가질 수 있을 때 까지 휴식

예제로 확인해 보자

value
먼저 마찬가지로 임계영역으로 들어가기 위해 lock 쥐기위한 경합을 하는 과정은 같음

위 함수에서 임계영역에서 동작을 하기 위해서는 value라는 값을 1을 가져야만 동작 가능

lock메서드를 먼저 살펴보면 만약 value를 누군가가 취득하고 있다면 다음에 자신의 차례가 되어서 lock을 취득할 수 있게 되면 깨워달라는 큐에 자기 자신을 넣게 되고 else에서 value를 획득할 수 있으면 그 value값을 쥐고 value값을 0 으로 바꿈

unlock 메서드도 간단하게 보면 lock 해제할때 큐에 하나라도 대기중인게 있으면 깨우고 아닐경우 value를 1로 바꿈

value값을 통한 임계영역에서 단 하나의 프로세스/스레드 가 실행될 수 있는 장치

guard

value라는 값 자체도 여러 스레드가 접근 하는 공유되는 데이터이기 때문에

임계영역 안에서 안전하게 보호 받으면서 그 값을 바꿔야 함. ( race condition 위험)
=> 안전하게 보호하기 위한 장치가 guard

guard의 사용예를 보자

value값을 바꿔주기 전에 guard를 취득하기위해 서로 경합을 하게되고 그 중 한개의 프로세스/스레드가 임계 영역안에 하나만 들어오게 될 경우에만 value값을 바꾸는 로직 실행 후 다시 guard를 0으로 바꿈 ( 위에 스핀락과 비슷한 맥락 )

간단하게 정리

  • 큐에 들어가서 대기 하고 있을게( lock에서 큐에 넣음 ) 깨워줘(unlock에서 깨워줘) ! => cpu 낭비 최소화
  • test and set -> atomic 명령어 사용

뮤텍스가 스핀락 보다 좋을까??

멀티 코어 환경에서 임계 영역에서의 작업이 컨텍스트 스위칭보다 빨리 끝나면 스핀락이 뮤텍스보다 이점이 있음

  • 싱글 코어에서 작동을 할때는 무조건 cs가 일어나지만 멀티 코어에서 t1 t2가 각각 한개의 코어에서 작동을 할때는 cs가 일어나지 않기 때문에 스핀락이 이득

3. 세마포 ( Semaphore )

signal mechanism을 가진, 하나 이상의 프로세스/스레드가 임계 영역에 접근 가능하도록 하는 장치

뮤텍스와 거의 유사하므로 다른부분만 보고 넘어가보자

  1. 메서드 이름이 바뀜
  2. value가 여러 값을 가질 수 있음 ( mutex는 1 or 0 )
  3. wait 메서드에서 value를 차감하는 로직으로 바뀜
  4. signal 메서드에서 value를 더하는 로직으로 바뀜

왜 이렇게 바꿨을까?

임계영역에 하나 이상의 프로세스/스레드를 들어갈 수 있게 하기 위함
=> 가게 (임계 영역) 안에 좌석 (value)이 3개라면 3명(스레드)이 모두 사용할 수 있음

물론 세마포도 mutual exclusion을 보장하게 만들수 있다-> value를 1을 가지게 하면됨

그리고 이렇게 value를 1을 가질때

이진 세마포 ( Binary Semaphore )라고 함 ( 1이 아닐때는 카운팅 세마포 )

세마포의 특별한 기능

  • 앞서 설명한 세마포의 signal mechanism 의미 = 순서를 정해줄 때 사용
  • 반드시 signal과 wait가 같은 프로세스/스레드 안에서 실행될 필요가 없음

뮤텍스와 이진 세마포는 같은것이 아닌가?..


뮤텍스 ( Mutex ) 와 이진 세마포 ( Binary Semaphore )

둘은 같아보이지만 같지 않다

  • 뮤텍스는 락을 가진 자만 락을 해제 할 수 있지만 세마포는 그렇지 않음
    => 이진 세마포는 signal과 wait를 날리는 존재가 다를 수 있음
  • 뮤텍스는 priority inheritance 속성을 가짐 ( 세마포는 없는 속성 )
    => 여러 프로세스/스레드가 동시에 실행될 경우 CPU에서 CS가 발생하여 누구를 먼저 실행시킬지를 정해야함 이를 스케쥴링이라고 함

스케쥴링의 방식에는 여러가지가 있는데 그중 하나가 프로세스/스레드의 우선 순위에 따라서 더 높은 우선순위를 가진쪽을 실행시키는 방법이 있다. 하지만 위의 경우에는 같은 자원에 대해 경합을 하면서 서로 lock을 취득하려고 할때 생기는 현상이 있음

프로세스로 예를 들어보자

프로세스들 (P1 , P2) 이 있고 P1의 우선순위가 더 높다고 가정
1. P2가 먼저 진행을 하고 lock을 쥔 상태에서 임계 영역안에서 동작을 하고 있음
2. 그러다가 스케쥴링이 되어서 P1이 실행 되다가 lock 쥐려고 하지만 lock은 지금 P2가 사용하고 있기때문에 P1은 더이상 진행할 수 없음
=> 이떄부터 P1은 우선순위가 낮은 P2에 의존성을 갖게 됨 ( 우선순위가 높음에도 불구하고 아무 작업도 못함 )

뮤텍스에서는 이문제를 해결하는 방법으로

P2의 우선순위를 P1만큼 올려버리고 스케쥴링을 할때 P2의 우선순위가 높은걸로 보고 P2를 먼저 실행시키고 임계영역에서 빨리 빠져나오게 함

정리

상호 배제만 필요하다면 뮤텍스 , 작업 간의 실행 순서 동기화가 필요하면 세마포


디테일한 부분은 OS나 언어에 따라 다를 수 있으니 더 공부해야함.. 이게 기초라니;;..

profile
내일부터 공부 해야지

0개의 댓글