Dining-Philosopher PS
0x10. Problem
0x11. situation
- N명의 철학자(philosopher)가 원형 테이블에 앉아 있음
- 각 철학자 사이에는 포크(fork)가 하나씩 존재 (총 N개)
이 젓가락 대신 상태로 shared resource 추상화
-
철학자는 세 가지 상태 반복:
- 생각(thinking)
- 먹기(eating)
- hungry
-
먹기 위해서는:
- 왼쪽 포크 + 오른쪽 포크 둘 다 필요
0x12. problem aspect
deadlock PS
- 모든 철학자가:
- 왼쪽 포크만 잡고
- 오른쪽 포크를 기다림 → 아무도 먹지 못함 (영원히)
[(draft yet): starvation]
- 특정 철학자는 계속 포크를 못 얻을 수 있음
0x20. IDEA
0x21. IDEA1: pick up only both
DEF
- 두 포크를 한 번에 같이 얻을 수 있을 때만 집는다
- 아니면 아무 것도 안 잡고 대기
HOW
deadlock PS 발생 조건중 hold-and-wait를 없앰
0x22. IDEA2: asymmetric coding
DEF
- 짝수: 왼쪽 → 오른쪽
- 홀수: 오른쪽 → 왼쪽
HOW
deadlock PS 발생 조건중 circular waiting을 없앰
- 모두 같은 방향으로 resource 요청하지 않음
- cycle 구조 형성 불가능
0x23. IDEA3: allow at most 4 to sit together
DEF
- 동시에 식사 시도 가능한 철학자 수를 N-1로 제한
HOW
deadlock PS 발생 조건중 circular waiting을 "간접적으로" 없앰
- 모든 사람이 동시에 resource chain 만들 수 없음
- 반드시 빈 slot 존재 → cycle 끊김
0x30. IMPL
0x31. idea1 with Monitor
monitor dining_philosopher
{
enum { thinking, eating, hungry } state[5];
condition self[5];
void pickup(int i) {
state[i] = hungry;
test(i);
while (state[i] != eating) {
self[i].wait();
}
}
void putdown(int i) {
state[i] = thinking;
int left = (i+4) % 5;
int right = (i+1) % 5;
test(left);
test(right);
}
void test(int i) {
int left = (i+4) % 5;
int right = (i+1) % 5;
if (
state[left] != eating
&& state[right] != eating
&& state[i] == hungry
) {
state[i] = eating;
self[i].signal();
}
}
void init() {
for (int i = 0; i < 5; i++) {
state[i] = thinking;
}
}
}each Philosopher:
{
pickup(i);
eat();
putdown(i);
think();
} while (1)