이 글에서는 C 프로그래밍 언어에서 스레드(thread)를 사용하여 1 2 3 시퀀스를 무한히 반복해서 출력하는 방법을 알아보겠습니다.
목표 출력 결과
먼저 우리가 만들고자 하는 코드의 예상 출력은 다음과 같습니다.
1 2 3 1 2 3 1 2 3 1 2 3
구현 아이디어
이 문제를 해결하려면 C 언어에서 세 개의 스레드가 동시에 병렬로 실행되도록 구성해야 합니다.
핵심 개념은 다음과 같습니다.
- 세 개의 스레드가 각각 1, 2, 3 중 하나의 숫자를 담당합니다.
- 초기값이 1로 설정된 공유 변수를 두고, 각 스레드는 이전 값에 따라 자신의 차례인지 판단합니다.
- 함수 내부에서 무한 루프를 실행하며, 뮤텍스(mutex)와 조건 변수(condition variable)를 사용해 스레드 간 실행 순서를 동기화합니다.
이러한 동기화 기법 덕분에 여러 스레드가 경쟁하더라도 항상 1 → 2 → 3 순서대로 출력이 유지됩니다.
예제 코드
아래는 위 아이디어를 실제로 구현한 전체 프로그램입니다.
#include <stdio.h>
#include <pthread.h>
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3 = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int value = 1;
void *foo(void *n){
while(1) {
pthread_mutex_lock(&lock);
if (value != (int)*(int*)n) {
if ((int)*(int*)n == 1) {
pthread_cond_wait(&cond1, &lock);
} else if ((int)*(int*)n == 2) {
pthread_cond_wait(&cond2, &lock);
} else {
pthread_cond_wait(&cond3, &lock);
}
}
printf("%d ", *(int*)n);
if (value == 3) {
value = 1;
pthread_cond_signal(&cond1);
}
else if(value == 1) {
value = 2;
pthread_cond_signal(&cond2);
} else if (value == 2) {
value = 3;
pthread_cond_signal(&cond3);
}
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(){
pthread_t tid1, tid2, tid3;
int n1 = 1, n2 = 2, n3 = 3;
pthread_create(&tid1, NULL, foo, (void *)&n1);
pthread_create(&tid2, NULL, foo, (void *)&n2);
pthread_create(&tid3, NULL, foo, (void *)&n3);
while(1);
return 0;
}코드 설명
- 조건 변수(cond1, cond2, cond3): 각 스레드가 자신의 차례를 기다릴 때 사용되는 신호입니다.
- 뮤텍스(lock): 공유 변수
value에 대한 접근을 보호하여 경쟁 상태(race condition)를 방지합니다. - foo 함수: 각 스레드가 실행할 함수로, 자신의 숫자가 현재 값과 일치하지 않으면 조건 변수에서 대기하고, 일치하면 숫자를 출력한 뒤 다음 스레드에 신호를 보냅니다.
- main 함수: 세 개의 스레드를 생성하고, 메인 스레드는 무한 루프로 대기합니다.
실행 결과
프로그램을 컴파일하고 실행하면 다음과 같이 시퀀스가 끝없이 반복 출력됩니다.
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3….
컴파일 시에는 pthread 라이브러리를 링크하기 위해 다음과 같이 -lpthread 옵션을 사용해야 합니다.
gcc program.c -o program -lpthread