[Philosophers] Day 01. 과제 소개 및 함수 공부 - pthread, mutex

jkeum·2021년 6월 9일
2

philosophers

목록 보기
1/5
post-custom-banner

과제 소개

Summary

이 프로젝트에서는 프로세스 스레딩의 기본 사항을 배웁니다.
스레드를 만드는 방법을 배웁니다.
뮤텍스를 발견하게 될 것입니다.

'식사하는 철학자 문제'를 검색하면 많이 나온다.

허용 함수

memset, printf, malloc, free, write,
usleep, gettimeofday,
pthread_create,pthread_detach, pthread_join,
pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_lock, pthread_mutex_unlock

함수 설명

pthread 함수

man pthread

POSIX 스레드는 프로세스 내에서 스레드라고 하는 여러 제어 흐름에 대한 요구 사항이 있는 응용 프로그램을 지원하는 함수 집합이다.
멀티 스레딩은 프로그램의 성능을 향상시키는 데 사용된다.

POSIX 스레드 함수는 이 섹션에서 다음 그룹으로 요약된다.

  • 스레드 루틴
  • 속성 개체 루틴
  • 뮤텍스 루틴
  • 조건 변수 루틴
  • 읽기 / 쓰기 잠금 루틴
  • 스레드 별 컨텍스트 루틴
  • 정리 루틴

#include <pthread.h>

  1. pthread_create
  • 함수 원형
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
  • pthread_t *thread
    : 스레드가 성공적으로 생성되었을 때 생성된 스레드를 식별하기 위해 사용되는 스레드 식별자이다. 성공적으로 함수가 호출되면 이곳에 스레드 ID가 저장된다.
  • const pthread_attr_t *attr
    : 스레드의 특성을 지정하기 위해 사용한다. 기본 스레드 특성을 이용할 때는 NULL을 보낸다. 스레드의 특성을 지정하려면 pthread_attr_init() 등의 함수로 초기화해야 한다.
  • void *(*start_routine)(void *)
    : 분기시켜 실행할 스레드 함수이다.
  • void *arg
    : 위의 스레드 함수에 전달되는 인자이다.

    새 실행 스레드를 만든다.
    성공적으로 생성되면 0을 리턴한다. 실패하면 thread가 설정되지 않고 에러 값을 리턴한다.
  1. pthread_detach
  • 함수 원형
    int pthread_detach(pthread_t thread)
  • pthread_t thread
    : detach 시킬 스레드이다.

    특정 스레드를 분리한다. 스레드가 독립적으로 동작하기를 원할 때 사용한다.
    pthread_create()만 사용하면 스레드가 끝나도 자원이 자동으로 해제되지 않는다. pthread_join()을 같이 사용해야 자원이 해제된다.
    하지만 pthread_detach()pthread_join()을 사용하지 않아도 자동으로 자원을 해제한다.
    pthread_detach()pthread_join()을 동시에 사용할 수는 없다.
    성공하면 0을 리턴하고 실패하면 에러 넘버를 리턴한다.
  1. pthread_join
  • 함수 원형
    int pthread_join(pthread_t thread, void **value_ptr)
  • pthread_t thread
    : 기다릴 스레드의 식별자이다.
  • void **value_ptr
    : pthread_create()start_routine()이 리턴하는 값을 넣는다.

    호출 스레드가 지정된 스레드의 종료를 기다리도록 한다.
    성공적으로 호출하면 0을 리턴한다. 실패하면 에러 넘버를 리턴한다.
    실패하면 좀비스레드가 되고, 이 좀비스레드는 자원을 소모해서 더 이상 스레드를 생성할 수 없게 된다.
  1. pthread_mutex_init
  • 함수 원형
    int pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
  • pthread_mutex_t *mutex
    : 초기화할 뮤텍스 객체이다.
  • const pthread_mutexattr_t *attr
    : 초기화할 뮤텍스의 특징을 지정할 수 있다. 기본 뮤텍스 특징을 사용할 때는 NULL을 보낸다.

    지정된 속성으로 뮤텍스를 초기화한다.
    뮤텍스는 fast, recursive, error checking 의 세 가지 중 하나를 선택할 수 있으며, 기본값은 fast 이다.
    성공하면 0을 리턴하고 실패하면 에러 값을 리턴한다.
  1. pthread_mutex_destroy
  • 함수 원형
    int pthread_mutex_destroy (pthread_mutex_t *mutex)
  • pthread_mutex_t *mutex
    : 제거할 뮤텍스이다.

    뮤텍스를 제거한다.
    뮤텍스는 pthread_mutex_init()으로 생성된 뮤텍스이다.
    뮤텍스를 제거하려면 그 뮤텍스는 반드시 unlock 상태여야 한다.
    성공하면 0을 리턴하고 실패하면 에러 값을 리턴한다.
  1. pthread_mutex_lock
  • 함수 원형
    int pthread_mutex_lock (pthread_mutex_t *mutex)
  • pthread_mutex_t *mutex
    : 잠그려는 뮤텍스이다.

    뮤텍스를 잠그고 사용할 수 있을 때까지 차단한다.
    만약 뮤텍스가 이미 잠겨있다면, 잠금이 풀릴 때까지 대기했다가 뮤텍스를 획득한다.
    성공하면 0을 리턴하고 실패하면 에러 값을 리턴한다.
  1. pthread_mutex_unlock
  • 함수 원형
    int pthread_mutex_unlock (pthread_mutex_t *mutex)
  • pthread_mutex_t *mutex
    : 잠금 해제할 뮤텍스이다.

    뮤텍스를 잠금 해제한다.
    잠겨있던 뮤텍스의 작업을 마치고 잠금을 해제하면 다른 스레드에서 뮤텍스를 잠글 수 있게 된다.
    성공하면 0을 리턴하고 실패하면 에러 값을 리턴한다.

pthread 함수를 사용한 코드를 컴파일 할 때는 다음과 같이 옵션을 넣어서 컴파일해야 한다.
gcc -g -pthread ...

그 외 함수

  1. usleep
    #include <unistd.h>
  • 함수 원형
    int usleep(useconds_t microseconds);
  • useconds_t microseconds
    : 대기할 시간이다. 단위는 마이크로초(1/100만)
    범위는 0~999999

    마이크로초 단위로 측정된 간격동안 스레드 실행을 일시중지한다.
    성공하면 0을 리턴하고 실패하면 에러 값을 리턴한다.
  1. gettimeofday
    #include <sys/time.h>
  • 함수 원형
    int gettimeofday(struct timeval *restrict tp, void *restrict tzp);
  • struct timeval *restrict tp
    : 1970-01-01 00:00:00 +0000 (UTC) 이후 경과된 초(seconds)와 micro초를 저장할 buffer
    struct timeval는 다음과 같다.
    struct timeval
    {
    	time_t		tv_sec;		// seconds
    	suseconds_t	tv_usec;	// microseconds
    };
  • void *restrict tzp
    : 현재 사용되지 않고 있다. NULL을 넣으면 된다.

    1970-01-01 00:00:00 +0000 (UTC) 이후부터 현재까지 경과된 초와 micro초(백만분의 1초) 값을 얻는 함수이다.
    정밀한 시간 정보가 필요한 경우에 사용한다.
    성공하면 0을 리턴하고 실패하면 에러 값을 리턴한다.

그 외 정보

int	main(void)
{
    pthread_t	th;
    
    pthread_create(&th, NULL, &routine1, NULL);
    printf("%ul\n", th);
    pthread_join(th, NULL);
    return (0);
}

이렇게 출력해보면 굉장히 큰 숫자가 나오는데, 이 숫자를 저 pthread 관련 함수들에서 스레드 식별자로 사용한다.
여기서는 unsigned long으로 출력했지만, unsigned long long이 될 수도 있고 int, char형이 될 수도 있다.
pthread_t는 불투명한 데이터 유형으로 처리된다.


마무리

새로운 함수가 너무 많아서 힘들었다.
사실 이게 Day01이지만 프로세스와 스레드, 뮤텍스부터 공부했다.
저 함수들을 어떻게 사용하게 될지.. 막막하다.


참고한 사이트:
Happy Programmer~ :: C언어: pthread 기본 함수들
RAEKWON :: [리눅스] 스레드(Thread) 개념과 예제(pthread_create, pthread_join, pthread_detach)
Pthread API 레퍼런스
POSIX 스레드 <pthread.h> - - NEOS POSIX 함수 설명서
IT 개발자 Note :: usleep(3) - 설정된 micro초(microsecond: 100만분의 1초) 동안 대기
IT 개발자 Note :: gettimeofday(2) - micro초단위의 시간 얻기
Youtube CodeVault - What is pthread_t?

profile
It's me, jkeum!
post-custom-banner

0개의 댓글