개요

POSIX 스레드(POSIX Threads, 약어: PThread)는 병렬적으로 작동하는 소프트웨어의 작성을 위해서 제공되는 표준 API다. 리눅스에서 제공하는 라이브러리중에 하나이며, user thread의 생성, lock, barriers와 같은 기능들을 제공한다. 이 Pthread를 이용하여 thread를 쉽게 구현할 수 있게 만든 것이 OpenMP이다.

사용법

포함

# include <pthread.h>
cc myprog.c -o myprog -lpthread

생성

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
  1. 첫번째 argument인 thread 는 스레드가 성공적으로 생성되었을때 생성된 스레드를 식별하기 위해서 사용되는 스레드 식별자이다.
  2. 두번째 argument인 attr 은 스레드 특성을 지정하기 위해서 사용하며, 기본 스레드 특성을 이용하고자 할 경우에 NULL 을 사용한다.
  3. 세번째 argument인 start_routine는 분기시켜서 실행할 스레드 함수이며,
  4. 네번째 argument인 arg는 스레드 함수의 인자이다.
  5. 성공적으로 생성될경우 0을 리턴한다.

종료

void pthread_exit(void *retval);
  1. 스레드를 종료시키고 자신을 생성한 함수에 retval을 리턴시킨다.

스레드 기다리기

int pthread_join(pthread_t th, void **thread_return);
  1. 목표 스레드가 완수될때까지 현재 스레드를 호출한 스레드의 실행을 정지시킨다.
  2. 0을 리턴하게 되며, thread_exit에서 인자로 넘겨진 retval이 명시된 thread_return을 통해서 리턴되어진다.

git처럼 스레드의 생성과 종료또한 많은 경우 fork-join패턴을 이용한다.

뮤텍스 생성

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr *attr);
pthread_mutex_t amutex = PTHREAD_MUTEX_INITIALIZER;

를 통해서 뮤텍스를 선언할 수 있다. mutex 는 여러개의 스레드가 공유하는 데이타를 보호하기 위해서 사용되는 도구로써, 보호하고자 하는 데이타를 다루는 코드영역을 단지 한번에 하나의 스레드만 실행가능 하도록 하는 방법으로 공유되는 데이타를 보호한다. 이러한 코드영역(하나의 스레드만 점유가능한)을 critical section 이라고 하며, mutex 관련 API 를 이용해서 관리할수 있다.pthread_mutex_init는 mutex 객체를 초기화 시키기 위해서 사용한다.

첫번째 인자로 주어지는 mutex 객체 mutex를 초기화시키며, 두번째 인자인 attr를 이용해서 mutex 특성을 변경할수 있다. 기본 mutex 특성을 이용하기 원한다면 NULL을 사용하면 된다. mutex 특성(종류)에는 “fast”, “recursive”, “error checking” 의 종류가 있으며, 기본으로 “fast” 가 사용된다.

뮤텍스 사용

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);

try lock은 뮤텍스를 기다리지 않고, EBUSY라는 에러를 리턴한다. 즉 try lock은 non-blocking 함수이다.

뮤텍스 삭제

int pthread_mutex_destroy(pthread_mutex_t *mutex);

pthread_mutex_destroy를 이용해서 제대로 mutex를 삭제하려면 이 mutex는 반드시 unlock 상태이여야 한다.

참고

  1. https://jungwoon.github.io/linux/2017/07/11/pthread/