여기부터 7장
Bounded-Buffer problem
Buffer의 크기가 N이고, data 생산자(Producer)와 소비자(consumer)가 있다고 하자.
Producer는 Buffer가 꽉 차면 동작하지 않고 consumer는 buffer가 비어있으면 동작하지 않는다.
semaphores
mutex
buffer는 critical section이므로 mutex로 mutual exclusion을 보장한다.
초기값 1
full
꽉 찬 버퍼의 수
초기값 0
empty
비어있는 버퍼의 수
초기값 N
ⓐ Producer:
wait(empty)
empty가 하나도 없으면 기다림
처음에는 N이므로 block()이 호출되지 않는다
wait(mutex)
buffer에 대한 독점권을 얻는다
mutex는 binary semaphore로 0이면 실행이 안 됨
처음에는 1이므로 실행됨
signal(mutex)
mutex를 0으로 설정해 Producer가 buffer에 접근할 수 없게 함
signal(full)
Buffer가 비어서 대기 상태인 Consumer가 있다면 wakeup 시킨다.
signal(full)을 호출하면 full이 0(초기값)이었다가 1이 되므로 Consumer가 실행된다.
ⓑ Consumer
wait(full)
처음에는 0이므로 block 됨
Produer가 실행되면 full이 0보다 커지므로 block되지 않음
wait(mutex)
처음에는 1이라 실행됨
0이면 Consumer가 block됨
signal(mutex)
wait(mutex)에서 mutex가 1이었으면 여기까지 옴
이제 0으로 해서 Consumer가 더이상 buffer에 접근할 수 없게 함
signal(empty)
empty 값이 0이라 대기하던 Producer가 empty가 1 늘어나서 실행됨
wait(mutex)가 wait(empty)나 wait(full)보다 먼저 호출되면 deadlock 발생
Consumer가 먼저 실행된다 하자.
mutex는 처음에 1이므로 wait(mutex)에 의해 0으로 바뀜
wait(full)을 호출하면 full의 초기값은 0이라 여기서 대기하게 됨
이제 Producer가 실행 됨
현재 Consumer가 mutex를 0으로 해놓은 상태이므로 wait(mutex)에서 기다리게 됨
따라서 둘 다 대기하게 됨
Producer가 실행되려면 Consumer에서 signal(mutex)를 호출해야 됨
그러려면 full이 0에서 1로 바뀌어야 되는데 이건 Producer가 signal(full)로 바꿔줌
근데 Producer가 대기 중이라 이게 안 됨
-> Deadlock
Semaphore를 쓰면 문제를 쉽게 해결할 수 있으나 전적으로 프로그래머에 의존적임
Readers-Writers promblem
Readers: 데이터를 읽기만 하고 update 하지 않음
Writer: 읽기 쓰기 다 함
여러 개의 Reader와 Writer가 하나일 때 공유 데이터를 어떻게 보호할 것인가?
Writer가 데이터에 접근 중이면 Reader는 접근하면 안 된다
반대도 마찬가지
다만 여러 개의 Reader는 동시에 접근 가능(데이터를 수정하지 않으니까)
Semaphores
read_count
Reader가 read할 때마다 1씩 증가함
즉 프로세스가 공유 데이터를 읽으려면 read_count를 1 증가시켜야 함
여러 Reader 프로세스가 동시에 공유 데이터를 읽을 때 mutex로 read_count를 보호함
mutex
read_count에 접근하기 위함
1로 초기화
rw_mutex
writer가 있을 때는 Reader가 공유 데이터에 접근하지 못 하도록 함
1로 초기화
Writer:
wait(rw_mutex)
초기값이 1이므로 Writer는 block되지 않음
그러고 나서 0으로 바꿔서 Reader가 접근하지 못 하게 함
signal(rw_mutex)
다 쓰면 rw_mutex를 1로 바꿔서 Reader가 접근할 수 있도록 함
Reader:
wait(mutex)
읽기 전에 read_count를 1 늘리고 다 읽고 나면 1 감소시킨다
그런데 이 read_count는 그 자체가 critical section이므로 우선 wait(mutex)로 독점권을 얻는다.
if (read_count == 1)
read_count == 1은 최초의 Reader가 있음을 의미하므로
wait(rw_mutex)를 호출해 Writer가 접근하지 못 하게 한다.
wait(mutex)
read_count에 접근하므로 다시 독점권을 얻음
signal(mutex)
다른 프로세스가 read_count를 증가시킬 수 있게 함
두 번째 Reader가 진입했다고 하자.
이미 rw_mutex는 lock이 걸려 있으므로 굳이 wait(rw_mutex)를 또 호출할 필요는 없음
읽기가 끝나면 wait(mutex) 호출 후 read_count--함
if(read_count == 0)
더이상 데이터에 접근하는 Reader가 없으므로 signal(rw_mutex)를 호출해 Writer가 접근할 수 있게 함
① wait(rw_mutex) (Writer)
rw_mutex가 0으로 바뀜
② 데이터 씀
③ wait(mutex) (Reader)
mutex = 0됨
④ wait(rw_mutex) (Reader)
rw_mutex가 0이므로 대기
첫 번째 Reader는 여기서 대기한다.
⑤ wait(mutex) (두 번째 Reader)
현재 mutex가 0이므로 두 번째부터는 Reader의 첫 줄 wait(mutex)에서 대기하게 됨
⑥ signal(rw_mutex) (Writer)
rw_mutex가 1이 됨
⑦ 읽음(첫 번째 Reader)
⑧ wait(mutex) (첫 번째 Reader)
mutex가 0이 됨
⑨ read_count-- (첫 번째 Reader)
read_count가 1이 됨
⑩ signal(mutex) (첫 번째 Reader)
mutex가 1이 되어 두 번째 Reader부터 실행됨
⑪ wait(rw_mutex) 두 번째 Reader
현재 read_count가 1이므로 wait(rw_mutex)에 의해 rw_mutex는 0이 됨
⑫ wait(rw_mutex) (Writer)
rw_mutex가 0이므로 대기
저거 없어도 잘 동작함
근데 여러 개의 Reader가 동시에 데이터를 읽을 수는 없게 된다
처음 wait(mutex) 하고 다 읽은 다음에 signal(mutex)하므로 읽는 작업을 독점하게 되는 것이다.
동작은 잘 되는데 효율이 떨어짐
Dining-Philosopher problem
5명의 철학자가 있고 젓가락도 딱 5개라고 하자. 이 경우 몇 명은 밥을 못 먹는다.
이 경우 Deadlock이 발생할 수 있다.
모든 철학자가 자기의 왼편에 있는 젓가락을 집었다(lock을 건다)고 하자.
이 때 한 철학자가 자기의 오른쪽에 있는 젓가락을 집으려고 하면(lock을 걸려고 하면) 영원히 기다리게 된다.
Monitor를 이용한 solution은 다음과 같다.
기본적으로 pickup - EAT - putdown의 순서로 실행된다.
test
오른쪽의 철학자 상태와 왼쪽의 철학자 상태를 확인한다.
자신은 HUNGRY고 양쪽의 철학자가 EATING이 아니면 젓가락 2개를 쓸 수 있음을 의미한다.
따라서 이 경우 자신의 상태를 EATING으로 바꾸고 자기 자신에 대한 signal()을 호출한다.
즉 자신의 프로세스를 하나 가져와 실행한다.
putdown
다 먹었으니까 THINKING으로 상태를 바꿈
왼쪽과 오른쪽 철학자에 대해 test 호출
왼쪽 철학자 입장에서는 우선 오른쪽(putdown을 호출한 철학자)는 HUNGRY가 아님
따라서 왼쪽 철학자 입장에서 자신의 왼쪽도 HUNGRY가 아니면 젓가락을 가져올 수 있다.
그리고 putdown을 호출한 철학자에 의해 대기 중이었으면 test()의 signal()에 의해 wakeup 된다.
그런데 Monitor 방법은 starvation 문제가 발생할 수 있다.
즉 어느 철학자가 먼저 젓가락을 가져갈 지 장담할 수 없어서
극단적인 경우 한 철학자가 계속 젓가락을 가져갈 수도 있다.
Bounded waiting에 의해 한 철학자가 pickup한 다음에 바로 pickup하지 말라는 법이 없어서 이런 문제가 발생하는 것
'강의노트 > 운영체제' 카테고리의 다른 글
[운영체제] 6주차: Process synchronzation (0) | 2021.04.12 |
---|---|
[운영체제] 5주차: 동기화를 위한 H/W적 수단 (0) | 2021.04.06 |
[운영체제] 5주차: 동기화 (0) | 2021.04.06 |
[운영체제] 4주차: CPU scheduling (0) | 2021.03.29 |
[운영체제] Term project: Nachos (0) | 2021.03.28 |