Synchronization: The Critical Section Problem(1)
Angrave System Programming/Synchronization 2019. 1. 15. 16:34Candidate Solutions
What is the Critical Section Problem?
pthread_mutex_lock() - one thread allowed at a time! (others will have to wait here)
... Do Critical Section stuff here!
pthread_mutex_unlock() - let other waiting threads continue
그렇다면 어떻게 이러한 lock과 unlock call을 수행할까요? mutual exclusion을 보증하는 알고리즘을 만들어볼 수 있을까요? 다음 코드는 잘못된 구현의 예입니다.
pthread_mutex_lock(p_mutex_t *m) { while(m->lock) {}; m->lock = 1;} pthread_mutex_unlock(p_mutex_t *m) { m->lock = 0; }
얼핏 보기에는 코드가 정상적으로 작동할 것 같습니다. 하나의 스레드가 mutex lock을 시도한다면, 다음 스레드는 lock이 해결될 때까지 기다릴 것입니다. 하지만 이러한 구현은 Mutual Exclusion을 만족하지 못합니다. 이 구현을 두 스레드가 동시에 동작하는 관점에서 좀 더 자세히 살펴봅시다. 다음 표의 순서대로 스레드가 동작한다고 생각해 봅시다.
Time | Thread 1 | Thread 2 |
---|---|---|
1 | while(lock) {} | |
2 | while(lock) {} | |
3 | lock = 1 | lock = 1 |
위와 같은 경우, race condition이 발생합니다. 이런 불운한 케이스에 두 스레드는 lock을 체크하여 잘못된 값을 읽어옵니다.이런 경우 더이상 진행이 불가능합니다.
Candidate solutions to the critical section problem.
// Candidate #1
wait until your flag is lowered
raise my flag
// Do Critical Section stuff
lower my flag
// Candidate #2
raise my flag
wait until your flag is lowered
// Do Critical Section stuff
lower my flag
Time | Thread 1 | Thread 2 |
---|---|---|
1 | raise flag | |
2 | raise flag | |
3 | wait ... | wait ... |
Turn-based solutions
// Candidate #3
wait until my turn is myid
// Do Critical Section stuff
turn = yourid
Desired properties for solutions to the Critical Section Problem?
- Mutual Exclusion - 스레드나 프로세스가 독접적인 접근을 얻습니다. 하나가 CS에 진입해 있다면 다른 하나는 이미 진입한 스레드나 프로세스가 CS를 나올 때까지 기다려야 합니다.
- Bounded Wait - 만약 스레드나 프로세스가 기다려야 한다면, 정해진 시간만을 기다려야 합니다.(무한히 기다리는 것이 허용되지 않습니다) bounded wait의 정확한 정의는 주어진 프로세스가 CS에 들어가기 전에 다른 프로세스가 진입할 수 있도록 상한선이 정해져야 한다는 것입니다.
- Progress - 만약 CS안에 스레드나 프로세스가 존재하지 않는다면 기다리지 않고 스레드나 프로세스가 진행되어야 합니다.
Turn and Flag solutions
\\ Candidate #4
raise my flag
if your flag is raised, wait until my turn
// Do Critical Section stuff
turn = yourid
lower my flag
한 강사와 다른 CS 교수가 그렇게 생각했습니다. 그러나 이 해결책을 분석하는 것은 까다롭습니다. 심지어 특정 주제에 대한 논문도 부정확한 정답을 포함하고 있습니다. 얼핏 봤을 땐 mutual exclusion, Bounded Wait, Progress를 모두 만족하는 것처럼 보입니다. turn based flag는 오직 같을 경우에만 사용되고 mutual exclusion도 만족하는 것처럼 보입니다. 반례를 찾을 수 있을까요?
후보4번은 다른스레드가 flag를 내릴 때까지 기다리지 않기 때문에 실패합니다. 다음 시나리오가 발생해 Mutual exclusive를 만족시키지 못하는 것을 알 수 있습니다.
처음 스레드가 코드를 두번 실행한다고 (turn flag가 두번째 스레드를 가리킴) 생각해봅시다. 첫 번째 스레드가 여전히 CS에 존재하는 중에 두 번째 스레드가 도착합니다. 이 두 번째 스레드는 즉시 CS안으로 진입합니다!
1 | 2 | raise my flag | |
2 | 2 | if your flag is raised, wait until my turn | raise my flag |
3 | 2 | // Do Critical Section stuff | if your flag is raised, wait until my turn(TRUE!) |
4 | 2 | // Do Critical Section stuff | // Do Critical Section stuff - OOPS |
'Angrave System Programming > Synchronization' 카테고리의 다른 글
Synchronization: The Critical Section Problem(3) (0) | 2019.01.16 |
---|---|
Synchronization: The Critical Section Problem(2) (0) | 2019.01.15 |
Synchronization: Working with Mutexes And Semaphores(2) (0) | 2019.01.15 |
Synchronization: Working with Mutexes And Semaphores(1) (0) | 2019.01.15 |
Synchronization: Counting Semaphores (0) | 2019.01.15 |