스핀락의 동작 방식
스핀락의 동작 원리는 대략 아래와 같다
volatile int lock = 0; // global
void doYourJob() {
while (test_and_set(&lock) == 1); // spinlock
... // critical section
lock = 0; // spinlock
}
스핀락의 동작 방식은 조건문이 false가 될 때까지 계속 while loop를 돌면서 끊임없이 확인하는 방식이다
오늘 주제에서는 test_and_set이 뭘 하는 친구인지는 중요하지 않다
오늘 중요한 것은 스핀락의 동작 방식은 loop를 탈출하기 위해 조건문을 끊임없이 확인한다는 점이다
스핀락의 문제점
조건문을 끊임없이 계속해서 확인한다는 것은 결국 CPU resource를 끊임없이 사용한다는 의미다
만약 어떤 스레드가 lock을 이미 취득해서 critical section에서 코드를 수행 중이라고 가정해 보자
이 스레드의 수행 시간이 길어지면 길어질수록 락을 취득하려고 기다리고 있는 다른 스레드들은 계속해서 무한 반복으로 조건문이 true인지 false인지 확인하고 있을 것이다
이렇게 CPU를 계속 낭비하게 되면,, 다른 일을 해야하는 스레드들이 CPU에서 작업할 수 있는 기회는 줄어들게 된다
결국 프로그램의 퍼포먼스는 안좋아 지고, 컴퓨터 시스템 전체적으로도 응답성이 나빠지게 된다
스핀락은 그 이름이 의미하는 것처럼 계속해서 CPU에서 spin 하며 동작하는 방식이라서, 자칫 잘못하면 어마무시한 CPU 리소스 낭비를 하게 되기 때문에 최대한 안 쓰는 것이 좋다
물론 스핀락도 장점이 있는 경우도 있는데 그런 경우는 아주 꼼꼼히 확인한 뒤에 확신이 서면 스핀락을 써야 한다
심지어 그런 상황에서 조차도 스핀락이 아니라 뮤텍스를 쓴다고 성능 상 크게 문제되지는 않을 거라서 최대한 스핀락이 아니라 뮤텍스를 쓰는 것이 좋다
쉬운코드는 본질에 충실합니다