❗️날짜별로 정리하여 복습하기를 원하기 때문에 내용이 길고 다소 정리되지 않았습니다.
여러개의 프로세스가 동시에
공유 데이터에 접근하는 것
💡 Counter++ is not atomic
if…

a→b→c→1→2→3 : 5
a→1→b→2→c→3 : 4
a→1→b→2→3→c : 6
여러 프로세스 또는 스레드가 공유 자원에 접근하는 코드 영역
한 프로세스 또는 스레드가 임계 영역에 진입했을 때 다른 프로세스 또는 스레드들이 동시에 접근하지 못하도록 하는 메커니즘
while (true){
aquire lock
critical section
release lock
remainder section
}
Lock 구현 방법 1 : Semaphores
wait(S){
while(S <= 0)
;//busy wait
S--;
}
signal(S){
S++;
}
//PRODUCER
while(1){
produce an item
...
wait(empty);
wait(mutex);
...
add item to buffer
...
signal(mutex);
signal(full);
}
//CONSUMER
while(1){
wait(full);
wait(mutex);
...
remove an item from buffer
...
signal(mutex);
signal(empty);
...
consume the item
...
}
//Writer
wait(rw_mutex);
...
writing is performed
...
signal(rw_mutex);
//Reader
wait(mutex);
read_count++;
if(read_count==1) wait(rw_mutex); //첫번째 Reader만 wait호출
signal(mutex);
...
reading is performed
...
wait(mutex);
read_count--;
if(read_count==0) signal(rw_mutex); //빠져나온 Reader가 마지막이면 signal호출
signal(mutex);

while(true){
wait(fork[i]);
wait(fork[(i+1)%5]);
//eat for awhile...
signal(fork[i]);
signal(fork[(i+1)%5]);
//think for awhile...
}

위 조건 중 하나라도 만족하지 않으면 효율성은 떨어지나 데드락이 발생하지 않음.
Resource Allocation Graph

좌측 → 우측으로 변하면 Cycle이 생겨서 데드락 발생 가능성이 생김.

위 Cycle이 생긴다고 데드락이 무조건 발생하지는 않음.
Cycle을 만들지 않도록 하는 방법이 Avoidence
다익스트라가 제안한 기법으로, 어떤 자원의 할당을 허용하는지에 관한 여부를 결정하기 전에, 미리 결정된 모든 자원들의 최대 가능한 할당량을 가지고 시뮬레이션 해서 Safe state에 들 수 있는지 여부를 검사 즉 대기중이 다른 프로세스들의 활동에 대한 교착 상태 가능성을 미리 조사하는 것
처음에 시스템이 총 12개의 자원을 가지고 있다고 가정
| (t=t0) | Max | Allocation | Need | Available |
|---|---|---|---|---|
| P0 | 10 | 5 | 5 | |
| P1 | 4 | 2 | 2 | |
| P2 | 9 | 2 | 7 |
P0~P2는 프로세스이고, Max는 각 프로세스마다 최대 자원 요청량, Allocation은 현재 프로세스에 할당 중인 자원의 양, Need는 남은 필요한 자원의 양(Max-Allocation) 입니다.
현재 t0일 때 프로세스에 할당된 자원의 합은 5+2+2=9개 입니다. 따라서 현재 Available 자원은 12 - 9 = 3개 입니다.
여기서 Safe sequence를 찾아보려고 합니다. 순서가 <P1, P0, P2> 일 때 안전 순서를 만족합니다.
P1은 2개가 이미 할당되어 있고, 2개를 추가적으로 할당받기를(Need) 기다리고 있습니다. 현재 Available 자원은 3개이므로, 이 중에 2개를 P1에게 할당해 줍니다. => 현재 Available은 3 - 2 = 1개P1은 자신에게 할당되어 있던 자원 4개를 모두 반납합니다. => 현재 Available은 1 + 4 = 5개P0은 자신에게 할당되어 있던 자원 10개를 모두 반납합니다. => 현재 Available은 0 + 10 = 10개P2에게 자원 7개를 할당해 줍니다. => 현재 Available은 10 - 7 = 3개P2는 자신에게 할당되어 있던 자원 9개를 모두 반납합니다. => 현재 Available은 3 + 9 = 12개이렇게 자원의 부족함 없이 올바르게 할당하여 모든 프로세스가 실행을 할 수 있었습니다.
만약 여기에서 P2 프로세스가 처음에 자원을 하나 더 할당받고 있었다면(즉, 2개가 아니라 3개) 운영체제가 가지고 있는 Available 자원은 12 - (5+2+3) = 2개 였을 것입니다.
이 상황에서는 처음에 P1에게 2개를 모두 주고, P1이 실행이 끝나고 자원을 모두 반납해도 Available 자원은 2 + 2 = 4개 뿐이므로, 이 자원으로는 나머지 P0이나 P2 프로세스를 해결해 줄 수 없습니다. (모두 4개보다 많은 양의 자원을 필요로 하고 있으므로)
따라서 P0, P2는 자원을 할당받기를 계속 기다려야 할 것입니다.
운영체제가 사전에 P2 프로세스가 자원을 하나 더 요청했을 때 할당해 주지 않고, P1이 먼저 끝나게 한다면 데드락이 발생하지 않았을 것입니다. 그러므로 은행원 알고리즘을 사용해서 자원 할당량을 사전에 파악하고 데드락을 회피할 수 있도록 하면 될 것입니다.