/ OS

스핀락, 세마포어 그리고 뮤텍스

스핀락(spinlock)과 세마포어(semaphore) 그리고 뮤텍스(mutex)는 모두 공유 자원에 대한 동시 접근을 제어하기 위해 쓰이는 락(lock)이다.

공유가 불가능한 자원에 동시 접근을 허용한다면, 동시성이 제어되지 않아 의도치않게 값이 덮어써지는 등 데이터가 일관성을 잃게 될 가능성이 생기기 때문이다. 이에 따라 락을 통해 공유 자원에 접근하는 부분, 즉 동시에 접근되면 안되는 구역인 임계 구역(critical section)의 진입을 통제함으로써 일관성을 보장한다.

스핀락, 세마포어 및 뮤텍스는 임계 구역에 진입하고 나갈 때 락과 언락(unlock)을 하는 방법이 서로 다르게 구현된다. 우선 스핀락은 임계 구역에 진입할 때까지 CPU를 놓지 않고 계속하여 락의 취득을 시도하는 busy waiting으로 구현된다. 세마포어와 뮤텍스도 busy waiting으로 구현될 수 있는데, 이 경우 락을 취득하는 방식에는 차이가 없다. 하지만 락을 요청한 후 취득할 때까지 CPU를 소모하지 않고 잠들어 있도록 대기 큐(wait queue)를 사용하도록 구현될 경우 차이가 생긴다. 금방 임계 구역에 진입이 불가능한 경우, 수행 가능한 다른 프로세스가 수행되고 있을 수 있도록 CPU를 낭비하지 않는 세마포어나 뮤텍스가 효율적이다. 하지만 금방 진입이 가능한 경우 프로세스가 잠들었다가 깨어나는 문맥 교환(context switch)이 필요없는 스핀락이 더 효율적이다.

세마포어는 임계 구역에 동시 진입을 허용할 프로세스의 수에 따라 1개만 허용하면 이진 세마포어(binary semaphore) 그 외에는 계수 세마포어(counting semaphore)라 한다. 뮤텍스도 임계 구역에 동시 진입을 허용할 프로세스가 1개이기 때문에 이진 세마포어와 동일하다 생각할 수 있지만 그렇지 않다. 뮤텍스의 경우, 락을 취득한 프로세스만이 언락을 할 수 있다는 점이 다르다. 따라서 뮤텍스를 통해 임계 구역에 진입한 프로세스가 비정상적으로 종료되거나 무한 루프에 빠진다면 같은 락을 바라보고 임계 구역에 진입하려고 시도하고 있던 프로세스는 영원히 진입할 수 없게 된다. 반면, 세마포어는 락의 동시 접근만을 제어할 뿐 언락을 시도하는 프로세스가 락을 취득했던 프로세스인지는 확인하지는 않는다. 이에 따라, 위와 같이 락을 취득했던 프로세스가 락을 해제하지 않은 채 비정상 종료가 되었다고 하더라도, 세마포어에서는 다른 프로세스가 대신 언락을 하여 무한히 대기하는 상황을 회피할 수 있다.

Reference