스레드 동기화 개요
스레드 동기화는 다중 스레드 프로그래밍에서 공유 자원 접근을 조정하기 위한 핵심 개념으로, 경쟁 조건과 데이터 불일치를 방지합니다. POSIX 스레드 라이브러리는 뮤텍스, 조건 변수, 읽기-쓰기 락, 세마포어 등 다양한 동기화 메커니즘을 제공합니다.
뮤텍스(Mutex)
뮤텍스는 동시에 단일 스레드만 공유 자원에 접근할 수 있도록 보장하여 경쟁 조건을 방지합니다.
스레드가 pthread_mutex_lock을 호출하면 락이 다른 스레드에 의해 점유되지 않았을 경우 해당 스레드가 락을 획득하고 실행을 계속합니다. 락이 이미 점유된 경우 현재 스레드는 락이 해제될 때까지 블록 상태가 됩니다.
pthread_mutex_unlock 호출 시 락이 해제되어 다른 스레드가 락을 획득할 수 있습니다.
주요 함수
int pthread_mutex_init(pthread_mutex_t *mtx, const pthread_mutexattr_t *attr);
int pthread_mutex_lock(pthread_mutex_t *mtx);
int pthread_mutex_unlock(pthread_mutex_t *mtx);
int pthread_mutex_destroy(pthread_mutex_t *mtx);
예제 코드
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mtx;
int counter = 0;
void *increment_counter(void *id) {
pthread_mutex_lock(&mtx);
counter++;
printf("스레드 %ld: counter = %d\n", (long)id, counter);
pthread_mutex_unlock(&mtx);
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_mutex_init(&mtx, NULL);
pthread_create(&t1, NULL, increment_counter, (void*)1);
pthread_create(&t2, NULL, increment_counter, (void*)2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&mtx);
return 0;
}
조건 변수(Condition Variable)
조건 변수는 특정 조건이 충족될 때 스레드를 깨워 스레드 간 조정과 대기를 구현합니다. 일반적으로 뮤텍스와 함께 사용됩니다.
주요 사용 사례
- 생산자-소비자 모델: 생산자가 데이터를 생성한 후 소비자에게 알림
- 작업 큐: 큐가 비었을 때 스레드 대기, 작업 도착 시 스레드 깨어남
- 스레드 풀: 풀 내 스레드가 작업 할당을 대기
주요 함수
int pthread_cond_init(pthread_cond_t *cnd, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cnd, pthread_mutex_t *mtx);
int pthread_cond_signal(pthread_cond_t *cnd);
int pthread_cond_broadcast(pthread_cond_t *cnd);
int pthread_cond_destroy(pthread_cond_t *cnd);
예제 코드
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mtx;
pthread_cond_t cnd;
int data_ready = 0;
void *producer_thread(void *arg) {
pthread_mutex_lock(&mtx);
data_ready = 1;
printf("생산자: 데이터 준비 완료\n");
pthread_cond_signal(&cnd);
pthread_mutex_unlock(&mtx);
return NULL;
}
void *consumer_thread(void *arg) {
pthread_mutex_lock(&mtx);
while (!data_ready) {
pthread_cond_wait(&cnd, &mtx);
}
printf("소비자: 데이터 처리 중\n");
pthread_mutex_unlock(&mtx);
return NULL;
}
int main() {
pthread_t prod, cons;
pthread_mutex_init(&mtx, NULL);
pthread_cond_init(&cnd, NULL);
pthread_create(&cons, NULL, consumer_thread, NULL);
pthread_create(&prod, NULL, producer_thread, NULL);
pthread_join(cons, NULL);
pthread_join(prod, NULL);
pthread_mutex_destroy(&mtx);
pthread_cond_destroy(&cnd);
return 0;
}