공유 자원에 대한 경쟁 상태(Race Condition)를 막아보자
여러 개의 스레드가 공유 자원을 쓰고 있을 때, 해당 공유 자원이 있는 임계영역(Critical Section)에 동시에 접근하게 되면 공유 자원에 대한 접근이 어떤 순서로 이루어졌는지에 따라 실행 결과가 동일하지 않고 실행할 때마다 결과가 달라진다.
즉, 경쟁 상태(Race Condition)가 발생한다.
따라서 해당 문제를 해결하기 위해 한 스레드가 임계 영역에 접근하면 다른 스레드들은 이 스레드가 이용하는 동안 해당 임계영역에 접근 할 수 없도록 한다. 즉, 두 개 이상의 스레드가 동시에 임계 영역에 접근하는 것을 막아야 하는데, 이를 상호 배제(Mutual Exclusion)라고 한다. 상호 배제는 Lock을 통해서 이루어지는데, 그중에 하나인 스핀락(SpinLock)에 대해서 알아보자.
스핀 락(Spin Lock)이란
임계 영역에 진입이 불가능할 때 진입이 가능할 때까지 루프를 돌면서 재시도하는 방식으로 구현된 락을 가르킨다.
락을 획득할 때까지 해당 스레드가 빙빙 돌고 있다는 것을 의미한다.
스핀 락은 바쁜 대기(Busy Wating)의 한 종류이다. 루프를 돌면서 CPU를 점유하고 있기 때문에 컨텍스트 스위칭이 발생하지 않는다. 하지만 오랜 시간 대기할 경우 CPU 자원이 낭비되므로 락을 설정 및 해제하는 주기가 짧고, 스레드 동기화가 빈번하게 일어나는 경우 컨텍스트 스위칭을 방지하기 위한 용도로 사용된다.
언제 사용하면 좋을까?
스핀 락을 사용하는 경우 vs 일반 락을 사용하는 경우
CPU 점유로 인한 대기 비용 < 컨텍스트 교환 비용이 클 경우에 스핀 락을 사용하면 성능 향상을 노릴 수 있다.
즉, 대기 시간이 짧아서 조금만 기다리면 락을 획득할 수 있는 경우 스핀 락을 사용하자.
예제 코드
class CustomSpinLock
{
private volatile bool _locked = false;
public void Enter()
{
while (_locked)
{
// 락이 풀리기를 대기한다.
}
// 락을 걸고 진입한다.
_locked = true;
}
public void Exit()
{
// 락을 해제한다.
_locked = false;
}
}
참고 사이트
'프로그래밍' 카테고리의 다른 글
Ubuntu에서 Nginx로 https 설정하기 (1) | 2024.09.04 |
---|---|
window 환경에서 NGINX 설치하고 실행하기 (0) | 2024.08.26 |
스레드 생성 이후에 언제 Handle을 반환해야 할까? (0) | 2024.08.07 |
Base64 인코딩이란? (3) | 2024.07.24 |
단일 장애 지점(SPOF)에 대해서 (1) | 2024.04.29 |
댓글