busy waiting은 어떤 프로세스가 자원을 사용하기 위해 실행을 중단하지 않고, 권한을 얻을 때까지 실행 상태를 유지하며 확인하는 것이다. mutex에서는 acquire()
함수 내부에서 lock을 얻기까지 반복문을 계속 실행하는 방식으로 구현한다.
다른 종류의 waiting은 sleep()
system call을 호출하여 대기 상태의 프로세스를 아예 waiting state로 전환했다가, 자원을 사용할 수 있는 상태가 되면 wakeup()
system call을 호출하여 ready queue에 다시 넣는 것이다.
운영체제의 어떤 이벤트들은 sleeping process를 손수 깨우지 않는 경우도 있으므로, busy waiting은 완전히 피할 수 없다.
wait()
and signal()
semaphore operations are not executed atomically, then mutual exclusion may be violated.wait()
나 signal()
내부에는 semaphore 변수 값을 1 키우거나 줄이는 연산이 있다. semaphore 변수는 critical resource이다. 따라서 semaphore 변수를 변경하는 연산은 critical section이다. 이 연산이 atomic하지 않으면, wait()
나 signal()
을 두 프로세스가 동시에 해당 함수들을 호출될 때 semaphore 변수에 대한 mutual exclusion이 보장되지 않는다.
deposit(amount)
and withdraw(amount)
. These two functions are passed the amount that is to be deposited or withdrawn from the bank account balance. Assume that a husband and wife share a bank account. Concurrently, the husband calls the withdraw()
function, and the wife calls deposit()
. Describe how a race condition is possible and what might be done to prevent the race condition from occurring.이 문제에서 잔고가 critical resource에 해당한다. 만약 동기화 없이 두 함수가 동시에 호출된다면, 두 함수는 각각 똑같은 기존 잔고를 불러와서 각각 예금 혹은 인출 결과를 반환한다. 결국 호출 순서에 따라 새로운 잔고는 (기존 잔고 + amount) 혹은 (기존 잔고 - amount)로 달라진다. 이는 전형적인 race condition에 해당한다. 이 문제를 해결하기 위해서는 동시에 critical resource에 접근하는 함수의 수가 최대 하나만 가능하게 해야 한다. 즉, 함수의 연산은 atomic해야 하고 함수 실행 순서가 순차적으로 결정되어야 한다.