본문 바로가기

cs/운영체제

13강 Process Synchronization 2

https://core.ewha.ac.kr/publicview/C0101020140404151340260748?vmode=f 

 

반효경 [운영체제] 13. Process Synchronization 2

설명이 없습니다.

core.ewha.ac.kr

 

자 대망의 세마포어

 

세마포어에대한 설명한다함

추상자료형? -> object 랑 operation 으로 구성된다.

정수 추상자료형이라 하면 정수 숫자 자료형이 있고 그 숫자에 대해 정의된 연산이 어떤게 있는가? 덧셈 뺄셈 곱셈 등등 있는것처럼

추상자료형은 논리적으로 정의하는것이지 컴퓨터에서 실제로 어떻게 구현되는지에 대해서는 별개의 이야기이다.

정리하자면 추상자료형은 뭐 어떻게 구현하던간에 어떤일을 하는건지 정의해놓는건데 +가 어떻게 실제로 더해서 돌려주는지 내알바 아니지 않는가? 그냥 +하면 컴퓨터가 알아서하고 그런거 구현하는거는 그런것만 하는애들 일이다 그니까 어쩃든 그런것들을 + 를 쓰면 더해준다는 약속들 목록을 나타내는 것을 추상 자료형이라 한다 선풍기에 미풍 약풍 강풍 기능 이 있는것처럼 기능 목록표 인거다 

 

세마포어도 일종의 추상자료형이라함

 

세마포어 변수 S 가 있다고하면

그 변수 S 는 정수 값을 가질수 있고 

그에대한 연산은 두가지가 정의되어있다.

P 연산과 V연산이 정의되어있다 위에 자료에 보면 나와있다.

P 연산과 V연산은 atomic(한번의 instruction 안에서 해결되도록) 하게 구현된다는것을 가정한다.

 

P 연산: 세마포어 변수값을 획득하는 과정이다.(공유 데이터를 획득하는 과정)

p 연산을 하게되면 s 값이 0이하인 동안 while 문을 돌면서 기다리는것이다. -> 자원을 다가져가고 기다리는 상태이다.

S값이 양수가 되면(누군가 내려놓으면 ) 자원을 획득하고 S 값을 1내린다.

여기서도 busy waiting 현상은 똑같이 일어난다.

 

V연산: 다 사용하고 난후 공유데이터를 반납하는 과정

걍 S 값 증가

 

 

세마포어 변수: 정수값이라 했는데 자원의 갯수라고 보면된다.

 

이제 이러한것을 사용하는 과정을보면

변수값 S가 5다: 자원이 5개 있는 것이다.

 

P연산을 한다. -> 자원을 하나 가져오는것이다 S는 4가된다(자원이 4개가 되는것이다)

 

V연산은 -> 자원을 다쓰고 내려놓는거니 S 가 증가한다.

 

앞전 강의의 lock 걸고 푸는 과정은 세마포어 변수값이 1이라 생각하면된다 (12강)

-> 이러면 P연산은 lock이 걸리고 V연산은 lock 이 풀리는것이다.

 

 

 

간단히 요약설명하자면

세마포어를 왜 사용하는가? -> lock 을 걸고 풀고 이것을 세마포어를 이용해서 간단하게 사용자에게 제공할수 있다.

공유자원을 획득하고 반납하는것을 세마포어가 처리해주는 것이다.

 

 

그래서  critical section 문제에 세마포어를 사용하게되면 -> 그냥 entry section 이 p연산 exit section 이 V연산이 되는것임

mutex 변수를 1로 놓고 (세마포어 변수)

lock 을 걸때 P연산을 해주고

빠져나올떄 V연산을 해주면  -> 이런 문제들이 해결된다.

 

프로그래머는 세마포어를 지원해준다면 P연산과 V연산만 해주면 되는것이고 구현은 시스템의 몫이다.

 

어쨋든 이런 방법을 써도 누군가가 critical section 에 들어가있다면 

기다리면서 busy waiting(spin lock) 을 할수 밖에없다.

 

하지만 세마포어의 구성방식을 busy waiting 방식으로만 구현할수 있는게 아니고 앞으로 살펴볼 Block & Wakeup(sleep lock 라고도 부름)방식을 사용할수도 있다.

 

 

앞쪽에서 이거 봤듯이

프로세스 I/O 같은거 할때 Blocked 되어서 I/O 다끝날때까지 cpu를 얻을수 있는 권한 자체가 없어지는 경우가 있었다.

 

공유데이터도 마찬가지이다. -> 위에도 공유데이터 큐가 있듯이

 

누군가 공유데이터를 쓰고있으면 쓸데없이 while문을 돌것이 아니라 아예 프로세스 자체를 blocked 시켜서 cpu 자체를 받을수 없게 만들어 버리고 공유데이터를 잡고있던 프로세스가 내놓으면 그때 깨어나서 ready queue 에 들어와서 cpu를 얻는 방식으로 구현하는것이

block & wakeup 방식으로 세마포어를 구현하는것이다.

 

 

 

이제 이 방식에서 세마포어는 

자원의 수를 나타내는 변수값과

세마포어 때문에 잠들어있는 프로세스들을 연결하기위한 큐가 하나 만들어진다.

 

-> 현재 세마포어를 획득할수 없으면 (자원의 수가 0 이하이면) 사용하려는 프로세스를 block 시키게 된다.

만약 이런경우에는 그 프로세스를 block 시키고 pcb를 세마포어 변수에 딸려있는 큐에다가 쭉 넣어둠

 

-> 누군가 자원을 내려놓으면 세마포어 변수가 1로 올라가면 block 된 프로세스중 하나를 깨우는 wake up을 시키게 된다.

 

block & wakeup 방식의 세마포어가 구체적으로 구현이 어떻게 되는지 살펴보자

 

S.value: 세마포어 변수 (자원의 양 과는 살짝 다르지만 어쩃든 도찐 개찐 음수가 가능함 음수가 되면 누군가가 기다리는것)

S.L : 대기 큐

 

P연산: 자원을 획득하는 과정 -> 자원의 여분이있다면 획득하고 

자원의 여분이 없다면 blocked 될것임 

 

자세히보면 일단 자원양 변수에서 1뺴줘버림

그리고 검사하는데 변수가 음수라면 이미 다 차지하고있는것이기 때문에 잠들게 되는것이다.

 

V연산: 자원을 다쓰고 반납하는것이다.

여기서는 자원을 반납하는것 뿐만 아니라

만약 자원을 기다리면서 잠들어있는 프로세스가 있다면 그것을 깨워주는 작업을 추가한다.

 

자원을 다쓰고난다음

일단 자원양 변수에 1을 더해버림

근데도 value 가 0 이하이면 누가 원하고 있는거니까 자원을 큐에 첫번째 대기하는 놈을 깨워준다.

 

 

그래서 busy wait 과 block/wakeup 기능중 뭐가 좋은데?
일반적으로 block/wakeup 이 효율적임

하지만 critical section이 매우 짧을시 오버헤드가 더 클수있다. 

 

 

세마포어를 두가지 방식으로 나눌수있다

1. 자원의 갯수가 하나인경우: 뮤텍스라 부름

-> 락과 언락을 걸기위해서 사용한다 -> 바이너리 세마포어라고도 부름

 

2.세마포어 변수값이 임의의 정수인 경우 counting semaphore

변수값이 5 막이런거로 될수있는것 

->여분의 자원을 세는용도로 사용함

 

세마포어는 사용할 때 주의점이 있다.

원치 않는 문제가 생길수 있는데

 

dead lock 와 starvation 이 있다.

 

dead lock 

위의 자료처럼 두 프로세스가 있는데 자원 s 와 q를 다얻어야 일할수있는 상황을 봐보자(예시상황 : 하드디스크 A에 있는걸 B로 카피하고싶다 같이 두가지 자원을 다 얻어야 실행할수 있는 상황)

 

S와Q는 1로 초기화된 세마포어이다.

 

근데 프로세스 0번에서 세마포어 S부터 얻고 cpu 를 1번 프로세스에 뺏겼는데 프로세스 1번에서 세마포어 Q를 얻어온경우 S 가 필요해서 기다리게됨 이렇게 서로 하나씩 획득하고 기다리기만하게됨 그래서 서로 일을 못하고 영원히 기다리는 고착상태에 들어가게됨

 

두 프로세스 모두 반환을 두 자원을 모두얻어서 일하고 난다음에 반환하기 때문에 데드락에 빠질수있다.

 

코드에 논리적으로는 문제가 없어보이지만 문제가 생길수 있다.

 

이런것을 해결하는 방법은 자원을 획득하는 순서를 똑같이 맞춰주면 문제가 해결된다. 

 

 

이런식으로 순서를 가져가면 된다.

이런식이라면 중간에 cpu를 빼앗기더라도 순서에 맞기때문에 데드락이 일어날 일은 없어진다 -> 프로그래머가 유의해서 작성해야하는부분이다.

 

 

starvation 문제가 여기서도 나오는데

위에 나온 데드락도 starvation의 일종으로 볼수 있을것이다.

 

-> 특정 프로세스들만 독식해서 다른 프로세스들은 자원을 받지 못하는 경우를 말한다 여기서는

 

철학자 문제라는 예시가 있다.

밥먹는 철학자라는 예시가 있는데

 

각 철학자들이 앉는데 양쪽에 있는 젓가락 두짝을 잡아야 밥을 먹는다고 가정해보자

2번이 먼저 먹으면 3번은 젓가락이 나올때까지 기다리는데 2번이 다먹기 직전에 4번이 젓가락을 잡으면 또밥을 못먹고 계속 이런식이면 계속해서 독식해서 3번을 굶겨 죽일수있다.

 

혹은 모두다 왼쪽 젓가락을 각자 들고있으면 다들 굶어죽는다. 이런것들이 있다.

 

 

 

 

 

 

 

 

 

 

 

 


https://worthpreading.tistory.com/90

 

뮤텍스(Mutex)와 세마포어(Semaphore)의 차이

이 글은 Medium에 개시된 글입니다. Medium에서 보시면 좀 더 유쾌한 환경에서 글을 보실 수 있습니다. 뮤텍스(Mutex)와 세마포어(Semaphore)의 차이 Toilet problem 동시성 프로그래밍의 가장 큰 숙제는 ‘공

worthpreading.tistory.com

 

세마포어와 뮤텍스에대한 부가설명