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

POSIX 스레드(Pthreads) 라이브러리 완벽 정리 – 개념부터 C 언어 예제까지


Pthreads는 POSIX 표준(IEEE 1003.1c)으로, 스레드 생성과 동기화를 위한 API를 정의한 규격입니다. 여기서 중요한 점은 Pthreads가 스레드의 동작 방식(behavior)에 대한 명세(specification)일 뿐, 그 자체가 구현체(implementation)는 아니라는 것입니다. 따라서 운영체제 설계자는 이 명세를 원하는 방식으로 자유롭게 구현할 수 있습니다.

실제로 많은 시스템이 Pthreads 명세를 구현하고 있으며, 대부분 Linux, Mac OS X, Solaris와 같은 UNIX 계열 운영체제입니다. Windows는 Pthreads를 기본적으로 지원하지 않지만, 서드파티(타사)에서 제공하는 구현체를 통해 사용할 수 있습니다.

Pthreads 예제 프로그램

아래의 C 프로그램은 Pthreads API의 기본적인 사용법을 보여주는 예제로, 별도의 스레드에서 음수가 아닌 정수의 합계를 계산하는 멀티스레드 프로그램입니다.

Pthreads 프로그램에서 개별 스레드는 지정된 함수에서 실행을 시작합니다. 아래 프로그램에서 그 역할을 하는 것이 바로 runner() 함수입니다. 프로그램이 시작되면 단일 제어 스레드가 main()에서 시작되고, 일부 초기화 작업을 마친 뒤 main()이 두 번째 스레드를 생성하여 runner() 함수에서 제어가 시작되도록 합니다. 이때 두 스레드는 전역 변수인 sum을 공유합니다.

#include <pthread.h>
#include <stdio.h>

int sum; /* 이 sum 데이터는 스레드(들)가 공유 */

/* 스레드가 호출하는 함수 */
void *runner(void *param);

int main(int argc, char *argv[])
{
    pthread_t tid;       /* 스레드 식별자 */
    pthread_attr_t attr; /* 스레드 속성 집합 */

    if (argc != 2) {
        fprintf(stderr, "usage: a.out \n");
        return -1;
    }

    if (atoi(argv[1]) < 0) {
        fprintf(stderr, "%d must be >= 0\n", atoi(argv[1]));
        return -1;
    }

    /* 기본 속성 가져오기 */
    pthread_attr_init(&attr);
    /* 스레드 생성 */
    pthread_create(&tid, &attr, runner, argv[1]);
    /* 스레드 종료 대기 */
    pthread_join(tid, NULL);

    printf("sum = %d\n", sum);
}

/* 스레드는 이 함수부터 제어를 시작한다 */
void *runner(void *param)
{
    int i, upper = atoi(param);
    sum = 0;

    for (i = 1; i <= upper; i++)
        sum += i;

    pthread_exit(0);
}

그림 4.9. Pthreads API를 사용하는 멀티스레드 C 프로그램

핵심 Pthreads API 함수 살펴보기

  • pthread_create(): 새로운 스레드를 생성합니다. 스레드 식별자, 속성, 실행할 함수, 전달 인자를 지정합니다.
  • pthread_join(): 지정한 스레드가 종료될 때까지 호출한 스레드를 대기시킵니다.
  • pthread_exit(): 해당 스레드의 실행을 종료합니다.
  • pthread_attr_init(): 스레드 속성 객체를 기본값으로 초기화합니다.

이처럼 Pthreads는 스레드 생성부터 종료, 동기화까지 스레드 프로그래밍에 필요한 표준화된 인터페이스를 제공하며, UNIX 계열 시스템에서 멀티스레드 애플리케이션을 개발할 때 가장 널리 사용되는 방식입니다.