본문 바로가기

Computer Science/OS

세마포의 구현 , 모니터의 개념

누군가 기다리고 있다면 S가 분명히 0일 것입니다.

 

만약 계속 기다리는 애들이 있다면 S는 건들이지 않고(S=0인 상태) 다른 프로세스가 동작을 할 것 입니다.

 

 

세마포의 구현

count로 0 이상일 때만 사용가능한 자원의 수로 생각해봅시다.

음수일 경우 세마포를 기다리는 프로세스의 갯수로 생각해봅시다.

 

 

내가 wait일 때는 무조건 count가 감소합니다. 0이면 음수가 되겠지요

signal연산 할 때는 무조건 count가 증가 합니다. 

 

대기일 때는

queue에서 기다리게 됩니다.

기다리면서 운영체제에게 block이라는 시스템 콜을 해서 대기열에 들어갑니다.

즉, 실행상태 -> 대기상태

 

나올 때는

count를 무조건 증가시킵니다.

즉, 대기상태 -> 준비상태 

 

wait 연산 자체가 임계영역입니다.

wait 중간에 인터럽트가 걸리면 안된다는 것이죠

 

wait와 signal는 임계영역에 들어가려는 연산인데 자체가 임계영역이 되어버립니다.

 

기본적인 해결책은 연상 수행 중에 인터럽트 금지 하는 것입니다.

cpu에 인터럽트 비트가 있습니다.

아에 비트를 없에서 인터럽트를 못하게 하는 것입니다.

그건 프로세스 하나가 있을 때는 할만 합니다.

 

프로세스가 여러개 있을 때 인터럽트를 금지하면 다른 프로세스는 놀고 있습니다.

 

TestAndSet 명령어를 사용해서 문제를 해결 합니다.

(wait에 들어갈 때 TestAndSet을 계속 실행해서 해결합니다.)

이건 바쁜 대기 문제가 있습니다.

 

이런 해결책으로 하면 바쁜 대기는 어처피 일어납니다.

하지만 임계영역이 짧고, 자주비게 되니깐 바쁜 대기가 유용할 수 있습니다.

 

 

Spin lock이란?

임계영역 진입이 가능할 때까지 루프를 돌면서 재시도 하는 lock

우리가 이해할 때 TestAndSet같은 것 입니다.

 

그럼 wait와 signal 코드를 어떻게 원자적으로 만들까요?

1. TestAndSet 명령어를 통해서 lock을 걸면 됩니다.

2. 단순한 시스템일경우 인터럽트 금지를 시킵니다.

 

 

여기서 타임아웃 = cpu스케줄링 할 때 "시간이 다됬어 나와 너 준비상태로 가" 하는 것입니다.

문제는 wait 중간에 걸리면 ?

 

원자적으로 만들어야 합니다.

단일 프로세스라면 인터럽트 금지

다중 프로세스라면 TestAndSet을 사용합니다.

 

 

이진 세마포 = 공유자원의 수가 1개

 

1번. 

처음에 남이 사용안했다면 세마포를 차지했겠지요

그 속(공유자원)에서 wait를 사용한다면? 자기를 기다립니다.

자기가 세마포를 차지했는데 또 자기가 wait를 실행하면 자기를 기다립니다.

영원히 멈춰있습니다. signal해도 큐에서 못나옵니다.

 

2번.

시그널을 먼저하면 사용 가능 자원이 1개 더 있다고 생각하게 됩니다.

그래서 다른 프로세스도 임계영역에 들어갈 수 있게 됩니다.

시그널을 먼저했기 때문에 임계영역에서 다른 사람이 못들어오게 하는 기능을 못합니다.

 

3번.

진행 중인 프로세스가 대기열에 들어가게 됩니다.

다른 프로세스도 못들어가게 됩니다.

 

 

세마포를 잘못 사용하는 경우

연산 wait()를 두 번 사용한 경우

  • 기아 (starvation) 또는 무한 정지 (indefinite blocking)
  • 나는 기아가 되고 다른 애들은 무한 정지가 됩니다.

 

연산 wait(), signal() 의 순서가 뒤바뀐 경우

  • 여러 프로세스들이 동시에 임계 영역 진입
  • 막아두는 효과를 못하니깐 다른 프로세스가 임계영역에 들어가게 됩니다.

 

두 프로세스가 각각 자원을 하나씩 보유하고, 상대방의 자원을 사용하려고 대기

  • 교착상태 (deadlock)가 일어나게 됩니다.
  • P0과 P1이 동시에 실행되면 
  • wait(Q)와 wait(S)에 영원히 묶여 있게 됩니다.

 

세마포의 단점

 

 

세마포의 단점을 해결하기 - 모니터

알고리즘들만

하드웨어로만 - TestAndSet

OS의 도움을 받아서 - 세마포

 

모니터란?

데이터와 함수? 클래스와 비슷합니다.

 

buffer는 공유 데이터 입니다.

버퍼에 put한다, get한다.

 

모니터 바깥에 Producor와 customer가 있습니다.

 

모니터란 공유자원에 함수로만 접근하게끔 만들어 놓은 것입니다.

 

하나의 프로세스만 모니터에 들어갈 수 있습니다.

 

 

모니터의 역활 - 하나의 프로세스만 모니터 안으로 들어갈 수 있다.

 

클래스의 개념과 비슷합니다.

거기에 프로세스가 한번에 하나씩만 들어가는 개념이 추가된 것입니다.

 

처음에 공유 데이터 변수를 선언합니다.

 

4번입니다.

모니터 내의 함수로만 데이터를 액세스 할 수 있습니다.

 

누군가 들어 있다면 큐에서 기다려야만 합니다.

 

예시는 통장 입니다.

 

공유 데이터는 통장잔고(balance) 입니다.

 

입금(credit)

출금(debit)

 

통장에 동시에 입금하고 출금하면 문제가 생깁니다.

 

synchronized 키워드로 모니터를 만들 수 있습니다.

 

어떤 프로세스가 synchronized에 붙어 있는 것에 하나만 할 수 있습니다.

하나의 스레드만 수행이 가능 합니다.

 

그리고 그 스레드는 객체를 잠궈버립니다.

 

모니터의 장점, 단점

wait와 signal 연산같은 것을 내가 정해야 되는데 

 

큐에다 넣는 코드, 빼는 코드는 컴파일러가 만듭니다.

결국 운영체제가 그런 기능을 제공해야 합니다.

 

 

 

모니터 내에서 중요한 개념인 - 조건 변수

 

728x90