운영체제 락 개념과 동기화 기법 (3. 고급 락(Spinlock & Semaphore) / 스핀락(Spinlock)과 세마포어(Semaphore))
2025. 2. 26. 12:25ㆍ정보기술/운영체제 (OS)
📖 스핀락(Spinlock)과 세마포어(Semaphore)
운영체제에서 멀티스레딩(Multithreading) 환경에서는 공유 자원(Shared Resource)에 대한 동기화(Synchronization) 가 필수적입니다.
스핀락(Spinlock) 과 세마포어(Semaphore) 는 동기화를 위한 중요한 기법으로, 각각의 목적과 사용 방식이 다릅니다.
✅ 스핀락(Spinlock)
🔹 스핀락이란?
- 락(🔒)이 해제될 때까지 CPU가 계속 바쁜 대기(Busy-Waiting)하면서 반복적으로 확인하는 방식.
- pthread_spinlock_t을 사용하여 구현.
- 빠른 락 해제가 예상되는 경우 뮤텍스(Mutex)보다 성능이 좋을 수 있음.
- 멀티코어 CPU 환경에서 커널 락과 같은 저수준 동기화에서 자주 사용.
🔹 스핀락의 특징
특징 | 설명 |
Busy-Waiting | Lock을 해제할 때까지 계속 CPU를 소모하면서 대기 |
빠른 락 해제 | Lock을 짧은 시간 동안만 유지하는 경우 효과적 |
멀티코어 환경 | 여러 개의 CPU가 동시에 실행되는 환경에서 적합 |
비효율적인 CPU 사용 | Lock이 장시간 유지되면 CPU를 낭비하게 됨 |
✅ C 코드 예제 (Spinlock 적용)
스핀락을 사용하여 하나의 스레드만 공유 자원에 접근하도록 제한하는 예제입니다.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_spinlock_t spinlock; // 스핀락 선언
int shared_data = 0; // 공유 자원
void* task(void* arg) {
printf("스레드 %ld: 락 획득 시도 중...\n", (long)arg);
pthread_spin_lock(&spinlock); // 🔒 스핀락 획득
printf("스레드 %ld: 락 획득! 작업 수행 중...\n", (long)arg);
sleep(1); // 작업 수행 (1초)
shared_data++; // 공유 데이터 변경
pthread_spin_unlock(&spinlock); // 🔓 스핀락 해제
printf("스레드 %ld: 락 해제 완료.\n", (long)arg);
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE); // 스핀락 초기화
pthread_create(&t1, NULL, task, (void*)1);
pthread_create(&t2, NULL, task, (void*)2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_spin_destroy(&spinlock); // 스핀락 제거
return 0;
}
✅ 실행 결과
스레드 1: 락 획득 시도 중...
스레드 1: 락 획득! 작업 수행 중...
스레드 1: 락 해제 완료.
스레드 2: 락 획득 시도 중...
스레드 2: 락 획득! 작업 수행 중...
스레드 2: 락 해제 완료.
- 한 번에 하나의 스레드만 락을 획득하여 공유 자원을 수정.
- 빠른 락 해제 시 효율적이지만, 락이 오래 유지되면 CPU 리소스를 낭비할 수 있음.
✅ 스핀락 사용 시 주의할 점
- CPU 과부하 문제
- 스핀락은 Lock이 해제될 때까지 계속 CPU를 사용하기 때문에 장시간 Lock이 유지되면 CPU 낭비가 발생할 수 있음.
- 해결책: 짧은 시간 동안만 Lock을 유지하는 경우에만 사용.
- 뮤텍스와의 차이점
- 뮤텍스는 Lock이 해제될 때까지 스레드를 대기 상태로 전환하여 CPU를 절약하지만,
스핀락은 계속 CPU를 사용하면서 Lock을 확인함. - 멀티코어 환경에서는 스핀락이 더 유리할 수 있음.
- 뮤텍스는 Lock이 해제될 때까지 스레드를 대기 상태로 전환하여 CPU를 절약하지만,
- 단일 코어 환경에서는 비효율적
- 단일 코어 환경에서는 스핀락이 다른 스레드가 Lock을 해제할 기회를 주지 않기 때문에 비효율적임.
✅ 세마포어(Semaphore)
🔹 세마포어란?
- N개의 스레드가 동시에 공유 자원에 접근할 수 있도록 제한하는 동기화 기법.
- sem_t을 사용하여 구현.
- 뮤텍스(Mutex)는 하나의 스레드만 Lock을 획득할 수 있지만, 세마포어는 count 값에 따라 여러 개의 스레드가 접근 가능.
🔹 세마포어의 특징
특징 | 설명 |
여러 개의 스레드 접근 가능 | count 값에 따라 N개의 스레드가 동시에 Lock을 획득 가능 |
뮤텍스와 차이점 | 뮤텍스는 1개 스레드만 접근 가능, 세마포어는 여러 개의 스레드가 접근 가능 |
POSIX 세마포어 사용 | sem_init(), sem_wait(), sem_post() 활용 |
데드락 방지 가능 | 세마포어 카운트를 조절하여 특정 자원에 대한 접근을 제어 가능 |
✅ C 코드 예제 (Semaphore 적용)
여러 개의 스레드가 동시에 실행될 수 있지만, 최대 2개의 스레드만 공유 자원에 접근할 수 있도록 제한하는 예제입니다.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t semaphore; // 세마포어 선언
void* worker(void* arg) {
sem_wait(&semaphore); // 🔒 세마포어 감소 (자원 획득)
printf("Worker %ld 실행 중...\n", (long)arg);
sleep(2); // 작업 수행 (2초)
printf("Worker %ld 종료.\n", (long)arg);
sem_post(&semaphore); // 🔓 세마포어 증가 (자원 반납)
return NULL;
}
int main() {
pthread_t threads[5];
sem_init(&semaphore, 0, 2); // 최대 2개 스레드만 접근 가능
for (long i = 0; i < 5; i++) {
pthread_create(&threads[i], NULL, worker, (void*)i);
}
for (int i = 0; i < 5; i++) {
pthread_join(threads[i], NULL);
}
sem_destroy(&semaphore); // 세마포어 제거
return 0;
}
✅ 실행 결과
Worker 0 실행 중...
Worker 1 실행 중...
(2초 후)
Worker 0 종료.
Worker 1 종료.
Worker 2 실행 중...
Worker 3 실행 중...
(2초 후)
Worker 2 종료.
Worker 3 종료.
Worker 4 실행 중...
(2초 후)
Worker 4 종료.
- 최대 2개의 스레드만 동시에 실행됨.
- 다른 스레드는 sem_wait()에서 대기하고 있다가, sem_post()가 호출되면 실행됨.
✅ 세마포어 사용 시 주의할 점
- 세마포어 카운트 설정 주의
- 너무 낮게 설정하면 병목 현상 발생, 너무 높으면 동기화 효과가 낮아짐.
- 사용 환경에 따라 적절한 값 설정이 필요.
- 데드락(Deadlock) 주의
- sem_wait()을 호출한 스레드가 sem_post()를 호출하지 않으면 세마포어가 영원히 해제되지 않음.
- 항상 sem_post()를 호출하도록 보장해야 함.
✅ 정리
동기화 기법 | 특징 | 사용 예시 |
스핀락(Spinlock) | Lock이 해제될 때까지 바쁜 대기(Busy-Waiting) | 커널 락, 짧은 시간 동안 Lock 유지 필요할 때 |
세마포어(Semaphore) | N개의 스레드가 동시에 접근 가능 | 데이터베이스 연결 제한, 네트워크 요청 동기화 |
'정보기술 > 운영체제 (OS)' 카테고리의 다른 글
운영체제 락 개념과 동기화 기법 (4. OS 내부 락과 문제 해결) (0) | 2025.02.26 |
---|---|
운영체제 락 개념과 동기화 기법 (Mutex, RLock, RWLock, 스핀락, 세마포어 비교 요약 정리) (0) | 2025.02.26 |
운영체제 락 개념과 동기화 기법 (2. 기본 락(Lock) / 2-3. 읽기-쓰기 락(Read-Write Lock, RWLock)) (0) | 2025.02.26 |
운영체제 락 개념과 동기화 기법 (2. 기본 락(Lock) / 2-2. 재진입 가능 락(Reentrant Lock, RLock)) (0) | 2025.02.26 |
운영체제 락 개념과 동기화 기법 (2. 기본 락(Lock) / 2-1. 뮤텍스(Mutex)) (0) | 2025.02.26 |