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 계열 시스템에서 멀티스레드 애플리케이션을 개발할 때 가장 널리 사용되는 방식입니다.