여러 개의 스레드가 주어졌을 때, 프로그램은 각 스레드의 우선순위에 따라 1부터 10까지의 숫자를 순서대로 출력해야 합니다.
스레드(Thread)란 무엇인가?
스레드는 프로그램 내부에서 실행되는 가벼운 프로세스입니다. 하나의 간단한 프로그램 안에도 수많은 스레드가 존재할 수 있습니다.
Java와 달리 C/C++ 언어 표준 자체는 멀티스레딩을 공식적으로 지원하지 않습니다. 대신 POSIX 스레드(Pthreads)가 C/C++ 환경에서 멀티스레딩을 구현할 때 사용되는 사실상의 표준입니다. C 언어는 멀티스레드 애플리케이션을 위한 내장 지원이 전혀 없으며, 이 기능은 완전히 운영체제에 의존하여 제공받게 됩니다.
프로그램에서의 작동 원리
스레드 관련 함수를 사용하려면 #include <pthread.h> 헤더 파일을 포함해야 합니다. 이 헤더 파일에는 pthread_create() 등 프로그램에서 사용할 수 있는 스레드 관련 모든 함수들이 정의되어 있습니다.
이번 예제의 목표는 gcc 컴파일러와 함께 제공되는 pthread 표준 라이브러리를 활용해 여러 개의 스레드를 동기화하는 것입니다. 핵심 아이디어는 다음과 같습니다. 첫 번째 스레드에서 1을 출력하고, 두 번째 스레드에서 2를 출력하는 식으로 교대로 진행하여 마지막 스레드까지 순차적으로 숫자를 출력합니다. 최종 출력 결과에는 스레드의 우선순위에 따라 정렬된 1부터 10까지의 숫자가 나타나게 됩니다.
알고리즘
시작
Step 1 -> 전역 변수 int MAX=10과 count=1 선언
Step 2 -> pthread_mutex_t 타입의 thr 변수와 pthread_cond_t 타입의 cond 변수 선언
Step 3 -> void *even(void *arg) 함수 선언
While(count < MAX) 반복
pthread_mutex_lock(&thr) 호출
While(count % 2 != 0) 반복
pthread_cond_wait(&cond, &thr) 호출
종료
count 값 출력 후 증가(count++)
pthread_mutex_unlock(&thr) 호출
pthread_cond_signal(&cond) 호출
종료
pthread_exit(0) 호출
Step 4 -> void *odd(void *arg) 함수 선언
While(count < MAX) 반복
pthread_mutex_lock(&thr) 호출
While(count % 2 != 1) 반복
pthread_cond_wait(&cond, &thr) 호출
종료
count 값 출력 후 증가(count++)
pthread_mutex_unlock(&thr) 호출
pthread_cond_signal(&cond) 호출
종료
pthread_exit(0) 호출
Step 5 -> main() 함수에서
pthread_t thread1과 pthread_t thread2 생성
pthread_mutex_init(&thr, 0) 호출
pthread_cond_init(&cond, 0) 호출
pthread_create(&thread1, 0, &even, NULL) 호출
pthread_create(&thread2, 0, &odd, NULL) 호출
pthread_join(thread1, 0) 호출
pthread_join(thread2, 0) 호출
pthread_mutex_destroy(&thr) 호출
pthread_cond_destroy(&cond) 호출
종료
예제 코드
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
int MAX = 10;
int count = 1;
pthread_mutex_t thr;
pthread_cond_t cond;
void *even(void *arg){
while(count < MAX) {
pthread_mutex_lock(&thr);
while(count % 2 != 0) {
pthread_cond_wait(&cond, &thr);
}
printf("%d ", count++);
pthread_mutex_unlock(&thr);
pthread_cond_signal(&cond);
}
pthread_exit(0);
}
void *odd(void *arg){
while(count < MAX) {
pthread_mutex_lock(&thr);
while(count % 2 != 1) {
pthread_cond_wait(&cond, &thr);
}
printf("%d ", count++);
pthread_mutex_unlock(&thr);
pthread_cond_signal(&cond);
}
pthread_exit(0);
}
int main(){
pthread_t thread1;
pthread_t thread2;
pthread_mutex_init(&thr, 0);
pthread_cond_init(&cond, 0);
pthread_create(&thread1, 0, &even, NULL);
pthread_create(&thread2, 0, &odd, NULL);
pthread_join(thread1, 0);
pthread_join(thread2, 0);
pthread_mutex_destroy(&thr);
pthread_cond_destroy(&cond);
return 0;
}
실행 결과
위 프로그램을 컴파일 후 실행하면 다음과 같은 출력 결과를 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 10
홀수 스레드(odd)와 짝수 스레드(even)가 뮤텍스(mutex)와 조건 변수(condition variable)를 통해 서로 차례를 양보하며 동작하기 때문에, 두 스레드가 동시에 실행되더라도 숫자가 항상 오름차순으로 정확하게 출력됩니다.