스핀락과 뮤텍스 (Spinlock & Mutex)
동기화(Synchronization)의 필요성
멀티프로세스 및 멀티스레드 환경에서는 여러 작업이 동시에 실행되면서 공유 데이터를 다루게 된다. 이 과정에서 동기화 기법이 필요한 이유는 다음 현상들을 방지하기 위해서다.
- 경쟁 상태 (Race Condition): 두 개 이상의 프로세스나 스레드가 공유 자원에 동시에 접근해서 실행 순서에 따라 결과값이 의도치 않게 달라질 수 있는 것.
- 임계 구역 (Critical Section): 여러 프로세스 혹은 스레드가 공유 자원에 접근하는 코드 영역, 레이스 컨디션이 발생할 수 있는 구역이다.
이러한 Critical Section 문제를 해결하고 데이터의 일관성을 보장하기 위해서는 한 프로세스가 임계 구역에 들어가 있을 때 다른 프로세스는 들어갈 수 없게 막는 상호 배제(Mutual Exclusion) 메커니즘이 필요하다. 대표적으로 스핀락과 뮤텍스가 있다.
스핀락 (Spinlock)
스핀락은 스레드가 임계 구역에 진입할 때까지 CPU를 점유하고 락(Lock) 취득을 계속 시도하는 동기화 기법이다.
- 동작 원리: 락 변수 상태를 계속 확인하는 Busy-waiting 방식으로 구현되고 이 과정에서 Wait queue를 가지지 않는다.
- 문맥 교환 (Context Switching): 운영체제의 스케줄링 지원을 받지 않아서 대기 중인 스레드에 대한 문맥 교환이 일어나지 않는다.
- 장단점: 프로세스가 잠들었다 깨어나는 문맥 교환 비용이 없어서 임계 구역 진입이 금방 가능한 상황에서는 매우 효율적이다. 다만 락을 기다리는 동안 CPU를 쉬지 않고 소모하기에 대기 시간이 길어지면 시스템 자원을 낭비할 수 있다.
acquire_lock:
mov eax, 1
xchg eax, [lock_var]
test eax, eax
jnz acquire_lock
ret
release_lock:
mov dword [lock_var], 0
ret
뮤텍스 (Mutex)
뮤텍스는 스레드가 락을 획득할 수 없을 때 CPU 점유를 포기하고 대기 상태로 전환하는 상호 배제 기법이다.
- 동작 원리: 공유 자원을 사용 중인 스레드가 있으면 다른 스레드는 락을 얻을 때까지 기다리는 동안 Sleep 상태로 전환해 대기 큐(Wait queue)로 보내진다. 이후에 락이 풀리면 깨어나서(Wake-up) 락 취득을 시도한다.
- 소유권: 뮤텍스는 Locking 메커니즘을 사용하기 때문에 락을 걸고 임계 구역에 진입한 프로세스나 스레드만 락을 해제(Unlock)할 수 있다.
- 장단점: 대기하는 동안 CPU 사이클을 낭비하진 않으나 프로세스가 잠들고 깨어나는 커널 호출, 문맥 교환 비용이 발생해 스핀락보다 구조적으로 무겁다. 그렇기 때문에 임계 영역의 작업이 길거나 언제 끝날지 모를 때 적합하다.
void mutex_lock(mutex_t *m){
if (atomic_compare_and_swap(&m->state, 0, 1) != 0) {
add_to_wait_queue(current_thread, m);
block();
}
}
void mutex_unlock(mutex_t *m){
m->state = 0;
if (!is_empty(m->wait_queue)) {
thread_t *t = remove_from_wait_queue(m);
wakeup(t);
}
}
기타 동기화 기법: 세마포어 (Semaphore)
스핀락과 뮤텍스 외에도 많이 쓰이는 기법으로 세마포어가 있다.
- 개념: 세마포어는 정수형 변수를 사용해서 하나 이상의 프로세스나 스레드가 공유 자원에 접근할 수 있게 허용하는 기법이다.
- 뮤텍스와 차이점: 뮤텍스는 임계 구역에 동시에 진입하는 것을 허용하는 스레드가 1개 뿐이고 락을 쥐고 있는 본인만 해제가 가능하다. 세마포어는 설정된 정수값(N개)만큼 동시 접근을 허용할 수 있고 락을 취득하지 않은 다른 프로세스도 언락을 시도할 수도 있다는 차이가 있다.
'공부한 것' 카테고리의 다른 글
| Context Switching (0) | 2026.06.05 |
|---|---|
| Calling Convention (0) | 2026.05.19 |
| Stack Canary (0) | 2026.05.18 |
| Shellcode - orw Shellcode (0) | 2026.05.17 |
| CVE-2026-28466 (0) | 2026.05.14 |