동기화 문제
Bouded Buffer Problem (= Producer Consumer Problem)
버퍼가 비어있을 때 소비자가 기다려야하고, 버퍼가 가득 찼을 때 생산자가 기다려야한다.
이러한 문제를 해결하기 위해 Semaphore full, empty를 사용하여 비어있지 않은 버퍼의 개수와 비어있는 버퍼의 개수를 파악하고 각 상황에 맞게 생산자와 소비자가 접근할 수 있다. 이때 추가적으로 Critical Section에 대한 권한을 주기 위해 Mutex를 사용한다.
아래 예시를 보면 생성자는 empty가 1이상 있을 때 wait에서 빠져나와 Mutex를 통해 진입하여 작업을 실행한다. 반대로 소비자는 버퍼에 1개 이상 값이 들어있을 때 접근할 수 있다.
Readers Writers Problem
reader와 writer가 동시에 작업을 처리한다면, reader가 값을 읽는 중에 writer가 값을 바꾼다면 reader의 결과 값의 일관성이 깨질 수 있다. 따라서 reader와 writer를 분리 시켜주어 writer는 reader가 critical section에 없을 때만 접근할 수 있다.
아래 예시에서 read_count에 대한 mutex를 통해 임계영역에 접근하고 read_count(=실행 중인 reader의 수)를 증가시킨다. 이때 처음 reader가 실행됐다면, 실행 중인 writer가 없는지 확인하고 mutex를 반환한다(= 다른 reader들이 들어오기 위해)
writer는 간단하게 실행 중인 reader가 있는지만 확인하고 없을 때 실행한다.
Dining Philosopher Problem
양쪽 젓가락을 모두 집었을 때만 밥을 먹을 수 있다. 각 철학자가 왼쪽 젓가락을 먼저 집고 오른쪽 젓가락을 집는다면, 오른쪽 젓가락을 오른쪽 철학자가 집었기 때문에 모든 철학자가 밥을 먹지 못하게된다.
식사하는 철학자 문제는 데드락 발생 조건 4가지를 모두 만족한다.
- 상호 배타(Mutual Exclusion): 젓가락(=공유 자원)은 한번에 한 철학자만 사용할 수 있다.
- 보유 및 대기(Hold and Wait): 집어든 젓가락 1개를 계속 든 채로 다른 젓가락을 기다린다.
- 비선점(No Preemption): 이미 누군가 가지고 있는 젓가락을 뺏을 수 없다.
- 환형대기(Circular Wait): 모든 철학자들이 자신의 오른쪽에 앉은 철학자가 젓가락을 놓기를 기다린다.
아래 예시에서는 모니터를 통해 3가지 상태를 나타내는 condition variable을 선언하여, 5명의 철학자가 가지게 한 다음, 헝그리 상태면 젓가락을 잡고, 다먹으면 양쪽 젓가락을 내려놓는다. 젓가락을 집을 때는 왼쪽과 오른쪽의 철학자가 밥을 먹고 있지 않을 때 집을 수 있다.