공유 자원 접근 순서에 따라 실행 결과가 달라지는 프로그램의 영역을 임계구역이라고 한다. 즉 프로그램에서 공유데이터(임계자원)을 이용하는 영역이다.
경쟁상태에서 공유자원을 사용하게 되는 영역이 임계영역이다.
여러 프로세스가 공유 데이터를 동시에 접근할 때 실행 순서에 따라 값이 달라지는 상황이다. 경쟁 상태는 상호배제를 하지 않았을 때 나타나는 현상이다.
두 쓰레드가 전역변수의 값을 증가시키는 상황을 가정하자. 아래와 같은 경우는 변수 값이 2로 의도한 대로 증가되었음을 확인할 수 있다.
하지만 아래와 같은 경우는 race condition(경쟁상태)에 놓여있다. 동시에 같은 공유 영역에 접근하여 연산했을 때 race condition이 발생하여 예상하지 못한 결과를 얻을 수 있다.
상호 배제(mutual exclusion)
여러 개의 프로세스가 공용 데이터에 동시에 접근 하는 것을 막아야 한다. 즉 한 프로세스가 공용 데이터를 사용하고 있으면 그 자원을 사용하지 못하도록 막거나 다른 프로세스가 그 자원을 사용하지 못하도록 막으면 이 문제를 피할 수 있다.
교착 상태(dead lock)
위의 상호 배제를 시행하면 또 다른 제어 문제가 발생한다. 그 중 하나는 교착 상태이다. 프로세스가 각자 프로그램을 실행하기 위해 두 자원 모두 엑세스 해야한다고 할 때, 프로세스는 두 자원 모두를 필요로 하므로 두 리소스를 사용하여 프로그램을 수행할 때까지 이미 소유한 리소스를 해제하지 않는다. 이때 교착 상태에 빠진다.
기아 상태(starvation)
프로세스들이 더 이상 진행하지 못하고 영구적으로 블락되어 있는 상태이다. 시스템 자원에 대한 경쟁 도중에 발생할 수 있고 프로세스 간의 통신 과정에도 발생할 수 있는 문제다. 여러 개의 작업이 서로 상대방의 작업만 끝나기를 기다리고 있기 때문에 결과적으로 아무것도 완료하지 못하는 상태가 된다.
💡 스레드의 실행 순서를 잘 조절해주지 않으면 비정상적인 상태가 발생한다. 이 문제는 특정한 순서대로 수행되었을 때 발생하는 것이다. 이런 문제가 발생하지 않도록 운영체제는 각 프로세스의 데이터 및 물리적 자원을 보호해야 한다. 그리고 프로세스에 수행하는 내용(기능)과 프로세스가 생성하는 결과는 서로 독립적이어야 한다.
💡 뮤텍스는 Locking 매커니즘으로 락을 걸은 쓰레드만이 임계 구역을 나갈 때 락을 해제할 수 있다. 하지만 세마포어는 Signaling 메커니즘으로 락을 걸지 않은 쓰레드도 signal을 사용해 락을 해제할 수 있다. 세마포어의 카운트를 1로 설정하면 뮤텍스처럼 활용할 수 있다.