Process Synchronization의 고전적 문제
Bounded-Buffer Problem (생산자-소비자 문제)
- 생산자 프로세스 : 공유 버퍼에 데이터를 만들어 집어넣는 역할
- 소비자 프로세스 : 공유 버퍼에서 데이터를 꺼내감
-
공유 버퍼이기 때문에 두 생산자 프로세스가 동시에 도착해서 동시에 데이터를 만들어 집어넣으면 문제 발생
-> 따라서 생산자 프로세스는 공유 버퍼가 비어있음을 확인하고, lock을 걸어 다른 프로세스의 접근을 차단한 후 작업이 끝나면 lock을 풀어 다른 프로세스가 공유 버퍼에 접근할 수 있게 해야 함
-
소비자 프로세스 또한 두 프로세스가 동시에 같은 데이터를 꺼내가려고 할 때 문제 발생
-> 따라서 full buffer를 확인한 후 lock을 걸어 데이터를 꺼낸 후 buffer 조작이 끝나면 lock을 풀어 다른 프로세스가 접근 가능하게 해야 한다.
-
buffer가 유한하기 때문에 생기는 문제
- 이미 buffer에 생산자 프로세스들이 데이터를 집어넣어 꽉 찬 상태에서, 소비자 프로세스가 오지 않고 생산자 프로세스가 접근해서 또 데이터를 넣으려고 하는 경우
- 생산자 프로세스 입장에서 사용할 수 있는 자원이 없는 상태
- 자원의 여분이 생길 때까지 (=비어있는 버퍼가 생길때까지 = 소비자 프로스세가 데이터를 꺼내갈 때까지) 기다려야 함
- 소비자 프로세스 입장에서, 소비자 프로세스들만 와서 꺼내갈 데이터가 없는 상태가 된 경우, 마찬가지로 생산자 프로세스가 데이터를 넣을 때까지 기다려야 함
Semaphore를 이용해야하는 경우
mutual exclusion : 동시에 접근하는 것을 막기 위해 공유 버퍼 전체에 lock을 걸어 다른 프로세스의 접근을 막을 때
resource count : buffer가 가득 차거나 비었을 때 자원의 개수를 세는 용도
Reader-Writers Problem
읽는 프로세스, 쓰는 프로세스 두 종류, 공유데이터 : DB
문제상황
- write 작업은 동시에 여럿이 하면 안되지만 read 작업은 가능
- write 하는 동안에는 lock을 걸고, 누군가 read할 때 read하려는 프로세스는 열어줌
해결
*readcount : 현재 DB에 접근중인 reader의 ㅅ
- writer가 DB에 접근 허가를 아직 얻지 못한 상태에서는 모든 대기중인 reader들을 다 DB에 접근하게 해준다
- writer는 대기 중인 reader가 하나도 없을 때 DB접근이 허용된다
- 일단 writer가 DB에 접근 중이면 reader들은 접근이 금지된다
- writer가 DB에서 빠져나가야만 Reader의 접근이 허용된다
Dining-Philosophers Prolem
- 5명의 철학자는 생각하거나 밥을 먹음
- 밥을 먹으려면 양쪽의 젓가락 두개를 잡아야 함
- 5명의 생각/식사 주기는 각각 다름
- 젓가락은 공유자원이기 때문에 옆 철학자가 밥을 먹고있으면 젓가락을 놓을 때까지 기다려야 함
Solution의 문제점
- Deadlock의 가능성 : 모두 왼쪽 젓가락만 잡으면 오른쪽 젓가락은 아무도 잡을 수 없음
-> 4명만 동시에 테이블에 앉을 수 있게 한다
-> 젓가락을 두 개 모두 집을 수 있을때만 젓가락을 집을 수 있게 한다
-> 비대칭 : 짝수 철학자는 왼쪽, 홀수 철학자는 오른쪽 젓가락부터 집게 한다.
Monitor
Semaphore의 문제점
- 코딩하기 힘들다
- 정확성의 입증이 어렵다
- 자발적 협력이 필요하다
- 한번의 실수가 모든 시스템에 치명적 영향
Monitor
- 동시 수행중인 프로세스 사이에서 abstract data type의 안전한 공유를 보장하기 위한 high-level synchronization construct
- 프로그래머가 lock을 걸 필요 없이 monitor 자체가 동시 접근을 허용하지 않음
- 공유 데이터를 접근하기 위한 프로시저는 내부 함수로 정의함. 프로시저를 통해서만 공유 데이터 접근 가능
- 모니터 내에서는 한번에 하나의 프로세스만이 활동 가능
- 프로그래머가 동기화 제약 조건을 명시적으로 코딩할 필요 없음
- 프로세스가 모니터 안에서 기다릴 수 있도록 하기 위해 condition variable 사용
condition variable
- condition variable은 wait와 signal 연산에 의해서만 접근 가능
- wait() : 자원의 여분이 있으면 바로 접근, 여분이 없어서 기다려야 한다면 기다리는 줄에 서서 기다리도록 함. 프로세스를 잠들게 함
- signal() : 접근 다 하고 빠져나갈 때 호출, 기다리고 있는 프로세스가 있으면 깨워줌. 기다리고 있는(잠들어있는) 프로세스가 없으면 아무 일도 안일어남
Bounded-Buffer Problem을 Monitor코드로 작성한 것
monitor가 애초에 중복접근 못하게 하기 때문에 lock걸 필요가 없어짐
Dining Philosophers의 Monitor버전
- 식사하는 부분은 모니터 내부의 함수로 선언됨
- 모니터 내부의 공유데이터 : lock 걸 필요 없음
- 젓가락 내려놓을 때 인접 철학자에 대해서 깨워줌