Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 프로그램에서 스레드 동기화를 활용해 숫자를 순서대로 출력하는 방법

여러 개의 스레드가 주어졌을 때, 프로그램은 각 스레드의 우선순위에 따라 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)를 통해 서로 차례를 양보하며 동작하기 때문에, 두 스레드가 동시에 실행되더라도 숫자가 항상 오름차순으로 정확하게 출력됩니다.