[42서울] Philosophers(1)

tamagoyakii·2022년 8월 12일
0

42seoul

목록 보기
10/19
post-thumbnail

🤔 무슨 과제인가요?

✅ Description

  • 필로소퍼! 는 철학자다. 다음은 철학자들이 프로그램에서 하는 행동이다.

    1. 한 명 이상의 철학자가 동그란 테이블에 앉아 테이블 한가운데 놓인 스파게티를 먹는다.
    2. 철학자는 먹고(eat), 자고(sleep), 생각(think)한다.
    3. 테이블에는 철학자의 수만큼의 포크가 있으며, 포크는 한 쌍의 철학자 사이에 하나씩 놓여있다.
    4. 스파게티를 먹기 위해서 철학자는 두 개의 포크를 사용해야 한다.
    5. 스파게티를 다 먹은 철학자는 테이블에 포크를 놓고 잠에 든다. 자고 일어나면 생각한다.
    6. 철학자는 굶지 않고 살아남아야 한다.
    7. 철학자끼리는 소통할 수 없다.
  • ❗️ 데이터 레이스(data race)가 있으면 안된다. ❗️

    💡 데이터 레이스(data race)란?

    데이터 레이스는 멀티 스레드(또는 프로세스) 환경에서 여러 스레드(또는 프로세스)가 하나의 공유 자원에 동시에 접근할 때 발생하는 문제다. 즉, 하나의 스레드에서 이미 사용하고 있는 공유 자원에 다른 스레드가 또 접근하게 될 때 공유 자원의 상태가 동기화되지 않으면서 문제가 생기는 것이다.

    이를 해결하기 위해 뮤텍스(Mutex) 또는 세마포어(Semaphore)를 이용해 작업 처리 순서를 제어하고 공유 자원에 대한 접근을 제어해야 한다.

결국 Philosophers"스레드(thread)"를 포크를 이용한 "뮤텍스(mutex)""멀티 스레딩(multi-threading)" 하는 과제다. 이에 관련된 내용은 다음 포스트에서 다루도록 하겠다.

✅ External functs.

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

예전에는 허용 함수가 많으면 좋았는데, 지금은... 걱정이 앞선다. 😭 처음 보는 함수들을 찬찬히 살펴보자 ㅎㅎ

1. usleep

  • syntax :
#include <unistd.h>

int usleep(useconds_t usec);
  • description :
    지정한 마이크로초 동안 대기 상태가 된다.
  • return :
    성공 시 0
    실패 시 -1

2. gettimeofday

  • syntax :
#include <sys/time.h>

int gettimeofday(struct timeval *restrict tv, struct timezone *restrict tz);
  • description :
    소스로직 중 특정구간의 수행시간 차이를 계산하기 위해 사용된다. tz(timezone) 구조체는 더 이상 사용되지 않기 때문에 일반적으로 NULL로 지정하며, tv(timeval)는 현재 시스템 시간을 구하기 위한 구조체로 다음과 같은 형태다.
struct timeval {
	time_t      tv_sec;     /* seconds */
	suseconds_t tv_usec;    /* microseconds */
};
  • return :
    성공 시 0
    실패 시 -1

3. pthread_create

  • syntax :
#include <pthread.h>

int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void *), void *restrict arg);
  • description :
    해당 함수를 사용하는 프로세스에 새로운 스레드를 만들고 해당 스레드의 식별자를 thread 포인터에 저장한다. 인자의 start_routine 함수를 arg 인자로 실행시키면서 시작된다. attr인자는 스레드의 특성을 지정하기 위한 용도로 사용되는데, NULL일 경우 기본 특성(joinable, non real-time)으로 지정된다.
  • return :
    성공 시 0
    실패 시 에러코드

4. pthread_join

  • syntax :
#include <pthread.h>

int pthread_join(pthread_t thread, void **retval);
  • description :
    thread 포인터가 가리키는 스레드가 종료되기를 기다린다. 해당 스레드가 종료되면 모든 자원을 반납한다. retval 포인터에는 스레드의 종료 상태가 저장된다. 스레드의 종료 코드를 알고 싶지 않다면 NULL을 넣으면 된다.
  • return :
    성공 시 0
    실패 시 에러코드

5. pthread_detach

  • syntax :
#include <pthread.h>

int pthread_detach(pthread_t thread);
  • description :
    thread 포인터가 가리키는 스레드를 분리시킨다. 분리된 스레드가 삭제될 때 해당 스레드의 자원은 자동으로 반납된다.
  • return :
    성공 시 0
    실패 시 에러코드

6. pthread_mutex_init

  • syntax :
#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);   
  • description :
    mutex 인자가 가리키는 뮤텍스 객체를 초기화시킨다. 뮤텍스는 스레드가 공유하는 영역을 보호하기 위해 사용된다. attr 인자는 뮤텍스의 특징(fast, recurisve)을 정의하기 위해 사용되며, NULL의 경우 기본값인 fast가 사용된다.
  • return :
    성공 시 0
    실패 시 에러코드

7. pthread_mutex_destroy

  • syntax :
#include <pthread.h>

int pthread_mutex_destroy(pthread_mutex_t *mutex);
  • description :
    mutex가 가리키는 뮤텍스 객체를 삭제하고 자원을 반납한다.
  • return :
    성공 시 0
    실패 시 에러코드

8. pthread_mutex_lock

  • syntax :
#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);
  • description :
    임계 영역에 진입하기 위해 뮤텍스 잠금을 요청한다. 만약 뮤텍스의 최근 상태가 unlocked라면 스레드는 잠금을 얻고 임계 영역에 진입하게 되고 리턴한다. 만약 다른 스레드가 이미 뮤텍스 잠금을 얻은 상태라면 잠금을 얻을 수 있을 때까지 기다리게 된다.
  • return :
    성공 시 0
    실패 시 에러코드

9. pthread_mutex_unlock

  • syntax :
#include <pthread.h>

int pthread_mutex_unlock(pthread_mutex_t *mutex);
  • description :
    뮤텍스 잠금을 되돌려 준다. fast 뮤텍스라면 언제나 unlocked 상태를 되돌려준다. recursive 뮤텍스라면 잠겨있는 뮤텍스의 수를 감소시키고 이 수가 0일 때 뮤텍스 잠금을 되돌려 준다.
  • return :
    성공 시 0
    실패 시 에러코드

서브젝트에 대해 살펴봤으니 이제 프로세스와 스레드, 뮤텍스와 임계 영역에 대해 자세히 알아보자!

참고

https://man7.org/linux/man-pages/man3/usleep.3.html
https://man7.org/linux/man-pages/man2/gettimeofday.2.html
https://man7.org/linux/man-pages/man3/pthread_create.3.html
https://man7.org/linux/man-pages/man3/pthread_detach.3.html
https://www.man7.org/linux/man-pages/man3/pthread_join.3.html
https://man7.org/linux/man-
https://www.delftstack.com/ko/howto/c/pthread_join-return-value-in-c/pages/man3/pthread_mutex_destroy.3p.html
https://man7.org/linux/man-pages/man3/pthread_mutex_lock.3p.html

0개의 댓글