운영체제(OS)

[OS] pthread

서노리 2022. 12. 6. 22:16
반응형

pthread lib

  • Unix 계열 POSIX 시스템에서 병렬적으로 작동하는 소프트웨어를 작성하기 위하여 제공하는 API
  • 쓰레드의 생성, 소멸, 제어 등을 편하게 구현 가능
  • pthread 라이브러리를 링크하기 위해 컴파일 시 -lpthread를 옵션으로 넣어야 함

 

pthread 함수

쓰레드 생성

int pthread_create(pthread_t *thread, const pthread_attr_t *attri, void *(*start_routine)(void*), void *arg);
  • ptrhead_t *thread
    - 함수를 실행할 쓰레드 변수의 포인터

  • const pthread_attr_t *attr
    - 쓰레드의 특성

  • void *(*start_routine)(void*)
    - 실행될 함수

  • void *arg
    - 함수의 인자의 포인터 (반드시 (void *)형 변환 필요)
    - 여러 개 전달 시 구조체로 전달해야 함
  • 리턴값
    - 성공 시 0, 실패 시 오류 번호

쓰레드 종료 대기

int pthread_join(pthread_t *thread, void **rval_ptr);
  • pthread_t *thread
    - 실행 종료를 기다릴 쓰레드 변수의 포인터

  • void **rval_ptr
    - 실행이 끝난 함수의 반환값이 저장되는 포인터
    - 함수의 반환 값이 void*이므로 void**가 되어야 함

  • 리턴값
    - 성공 시 0, 실패 시 오류 번호

 

쓰레드 종료

void pthread_exit(void *rval_ptr);
  • void *rval_ptr
    - 자신을 생성한 쓰레드에 rval_ptr 인자를 반환하고 쓰레드를 종료

  • 리턴값
    - 성공 시 0, 실패 시 오류 번호

쓰레드 분리

int pthread_detach(pthread_t tid);
  • pthread_t tid
    - 메인 쓰레드로부터 해당 쓰레드를 분리

  • 리턴값
    - 성공 시 0, 실패 시 오류 번호


Mutex Lock

pthread를 활용하여 쓰레드의 동기화와 공유 자원 동시 접근을 막는 뮤텍스를 구현할 수 있다.

뮤텍스 변수는 공유 데이터를 접근하는 것을 보호하는 락처럼 사용하며 동시에 단 하나의 쓰레드만이 뮤텍스 변수에 락을 걸 수 있다.

 

Mutex 관련 함수

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
  • 초기화할 mutex 변수의 포인터와 특성을 인자로 전달
  • 리턴값 - 성공 시 0, 실패 시 오류 번호

※ 함수의 사용대신 mutex = PTHREAD_MUTEX_INITIALIZER;로 초기화하는 방법도 존재

 

int pthread_mutex_lock(pthread_mutex_t *mutex);
  • 뮤텍스를 락하여 다른 쓰레드가 자원을 접근할 수 없도록 함
  • 다른 쓰레드가 이미 락을 건 상태에서 이 함수를 호출하면 언락될때까지 대기하게 됨

 

int pthread_mutex_unlock(pthread_mutex_t *mutex);
  • 뮤텍스의 락을 푸는 함수

 

int pthread_mutex_destroy(pthread_mutex_t *mutex);=
  • 사용이 끝난 뮤텍스와 이와 관련된 자원의 락을 해제하는 함수

 

Mutex 예제

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

int cnt = 0;
pthread_mutex_t mutex;

void *count(void *arg) {
    int i;
    char *name = (char*)arg;

    pthread_mutex_lock(&mutex);
    cnt = 0;
    for(i = 0; i < 10; i++) {
        printf("%s cnt: %d\n", name, cnt);
        cnt++;
        usleep(1);
    }
    pthread_mutex_unlock(&mutex);
}

int main() {
    pthread_t thread1, thread2;

    pthread_mutex_init(&mutex, NULL);

    pthread_create(&thread1, NULL, count, (void*)"thread1");
    pthread_create(&thread2, NULL, count, (void*)"thread2");

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    pthread_mutex_destroy(&mutex);
}


Mutex와 조건 변수

뮤텍스만을 이용하여 동기화를 하는 것은 프로세스가 지속적으로 뮤텍스 변수를 검사해야한다는 단점이 있기 때문에 조건 변수를 함께 사용한다. 하나의 쓰레드는 조건 변수에 시그널이 전달될 때까지 특정영역에서 대기 상태로 있어야한다.

 

조건 변수 관련 함수

int pthread_cond_init(pthread_cond_t *restrict condition, pthread_condattr_t *restrict attr);
  • 초기화할 조건 변수의 포인터와 특성을 인자로 전달

※ 함수의 사용대신 cond = PTHREAD_COND_INITIALIZER;로 초기화하는 방법도 존재

 

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
  • 뮤텍스의 락을 해제하고 기다리는 함수
  • 따라서 다른 쓰레드에서 뮤텍스의 락을 얻을 수 있음
  • 조건 변수에 시그널이 올 때까지 기다림

 

int pthread_cond_signal(pthread_cond_t *cond);
  • 조건 변수에 시그널을 보내 기다리고 있는 쓰레드를 깨우는 함수
  • 기다리는 쓰레드가 없다면 아무일도 일어나지 않음
  • 기다리는 쓰레드가 여러 개라면 단 하나의 쓰레드만 깨움

 

int pthread_cond_destroy(pthread_cond_t *condition);
  • 사용이 끝난 조건 변수를 해제하는 함수

 

조건 변수 사용 예제

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

pthread_mutex_t mutex;
pthread_cond_t cond;

int data = 0;

void *increase(void* arg) {
    while(1) {
        pthread_mutex_lock(&mutex);
        pthread_cond_signal(&cond);
        data++;
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
}

void *printData(void* arg) {
    while(1) {
        pthread_mutex_lock(&mutex);
        pthread_cond_wait(&cond, &mutex);
        printf("data: %d\n", data);
        pthread_mutex_unlock(&mutex);
    }
}

int main() {
    pthread_t thread1, thread2;

    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    pthread_create(&thread1, NULL, printData, NULL);
    pthread_create(&thread2, NULL, increase, NULL);
    

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    pthread_mutex_destroy(&mutex);
}


 

반응형

'운영체제(OS)' 카테고리의 다른 글

[OS] Hard Disk, Disk Scheduling  (0) 2022.12.08
[OS] File System  (0) 2022.12.07
[OS] Deadlock  (0) 2022.12.05
[OS] Semaphore  (0) 2022.12.04
[OS] Lock  (0) 2022.10.27