42Seoul/Philosophers

[Philosophers] 변수 및 허용 함수 정리

  • -
728x90

변수

  1. number_of_philosophers : 철학자 수(+ 포크의 수)
  2. time_to_die : 지난 번 식사로부터 식사를 마칠 때까지 남은 시간.
  3. time_to_eat : 밥 먹는 데 걸리는 시간. 두 개의 포크를 사용해야 한다.
  4. time_to_sleep : 잠자는 데 걸리는 시간.
  5. number_of_times_each_philospher_must_eat : 옵션이며, 식사 횟수가 이 변수의 값과 같아지면 프로그램 종료.

 

허용 함수

usleep

마이크로초 단위로 측정한 간격 동안 쓰레드 실행을 일시 중단한다.

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

int	main(int argc, char *argv[])
{
	printf("1초마다 출력 합니다.\n");
	for (int i = 0; i < 10; i++){
		printf("%d초\n", i + 1);
		usleep(1000000);
	}
	return (0);
}

 

gettimeofday

마이크로초 단위의 시간을 되돌려준다.

 

#include <sys/time.h>
#include <unistd.h>

struct timeval // 현재 시스템 시간을 저장하기위한 구조체
{
	long tv_sec;    // 초
	int tv_usec; // 마이크로초
}

struct timezone // 타임존 설정을 위한 구조체 (현재 사용되지 않음)
{
  int tz_minuteswest; // 그리니치 기준 서측으로 분(minute) 차(difference)
  int tz_dsttime;
}

int gettimeofday(struct timeval *tv, struct timezone *tz);

 

성공 시 0, 실패 시 -1을 반환

 

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

int	main(int argc, char *argv[])
{
	struct timeval	startTime, endTime;
	double			diff;

	printf("작업 1\n");
	gettimeofday(&startTime, NULL);
	usleep(10000000);
	printf("작업 2\n");
	gettimeofday(&endTime, NULL);
	diff = (endTime.tv_sec - startTime.tv_sec) + (endTime.tv_usec - startTime.tv_usec)/1000000;
	printf("대기한 시간은 %f 초 입니다.\n", diff);
	return (0);
}

 

pthread

POSIX 쓰레드의 약어. pthread는 모든 유닉스 계열 POSIX 시스템에서, 일반적으로 이용되는 라이브러리이다.

#include <pthread.h>

 

pthread_create

새로운 쓰레드를 생성하는 함수

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

pthread_t *thread : 쓰레드 식별자

const pthread_attr_t : 쓰레드 특성 지정

void *(start_routine)(void *) : 쓰레드가 실행되었을 때 시작할 함수

void *arg : 쓰레드가 실행되었을 때 시작할 함수의 매개변수

 

성공 시 0 반환, 실패 시 아래 에러들을 반환

  • [EAGAIN] : The system lacked the necessary resources to create another thread, or the system-imposed limit on the total number of threads in a process
  • [PTHREAD_THREADS_MAX] : would be exceeded.
  •  [EPERM] : The caller does not have appropriate permission to set the required scheduling parameters or scheduling policy.
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdlib.h>
#include <pthread.h>

void	*t_func(void *data)
{
	pid_t		pid;	// process id
	pthread_t	tid;	// thread id

	pid = getpid();			// process 식발자 가져오기
	tid = pthread_self();	// thread 식별자 가져오기

	char	*t_name = (char *)data;
	int		i = 0;

	while (i < 3)
	{
		printf("[%s] pid:%u, tid:%x --- %d\n",
		t_name, (unsigned int)pid, (unsigned int)tid, i);
		i++;
		usleep(1000000);	// 1초 대기
	}
}

int	main(int argc, char *argv[])
{
	pthread_t	thrd[2];
	int			tid;
	int			status;
	char		*t1 = "philo1";		// 1번 쓰레드 이름
	char		*t2 = "philo2";		// 2번 쓰레드 이름
	char		*tm = "main";		// 메인 쓰레드 이름

	usleep(1000000);

	// 1번 쓰레드 생성
	tid = pthread_create(&thrd[0], NULL, t_func, (void *)t1);
	if (tid < 0)	// 쓰레드 생성 실패시 -1을 반환
	{
		printf("error\n");
		exit(0);
	}
	// 2번 쓰레드 생성
	tid = pthread_create(&thrd[1], NULL, t_func, (void *)t2);
	if (tid < 0)
	{
		printf("error\n");
		exit(0);
	}
	// main 함수에서도 쓰레드에서 돌아가고 있는 동일한 함수 실행
	t_func((void *)tm);

	// 1, 2번 쓰레드 종료를 기다림
	pthread_join(thrd[0], (void **)&status);
	pthread_join(thrd[1], (void **)&status);
	return (0);
}

 

 

pthread_join

특정 쓰레드가 종료되기까지 기다린 후 쓰레드가 종료되면 실행한다.

첫 번째 매개변수는 쓰레드, 두 번째 매개변수는 해당 쓰레드 함수의 리턴값이다.

join된 쓰레드는 모두 반납된 쓰레드로 간주하며, 모든 자원을 반납하게 된다.

 

#include <pthread.h>

int pthread_join(pthread_t th, void **thread_return);

성공 시 0을 반환하고 실패 시 아래를 반환한다.

  • [EINVAL] : The implementation has detected that the value specified by thread does not refer to a joinable thread
  • [ESRCH] : No thread could be found corresponding to that specified by the given thread ID, thread
  • [EDEADLK] : A deadlock was detected or the value of thread specifies the calling thread.

 

pthread_detach

특정 쓰레드를 해제한다.

일반적으로 pthread_create를 통해 생성한 쓰레드는 쓰레드 종료 시점에 자동으로 자원이 해제되는 것이 아니다.

이를 해제해주는 것이 pthread_join과 pthread_detach이다.

 

pthread_join과의 차이는 쓰레드가 종료될때까지 기다리는 것과, 기다리지 않고 즉시 쓰레드를 해제하는 것이다.

 

성공시 0을 반환하고 실패 시 아래를 반환한다.

  • [EINVAL] : The implementation has detected that the value specified by thread does not refer to a joinable thread
  • [ESRCH] : No thread could be found corresponding
 #include <pthread.h>

int pthread_detach(pthread_t thread);

 

Mutex

mutex는 여러 개의 쓰레드가 공유하는 데이터를 보호하기 위한 것이다.

어떤 코드 영역에 대해 한 번에 하나의 쓰레드만 실행가능하도록 만듦으로써 공유되는 자원을 공유한다.

 

pthread_mutex_init

mutex를 만든다.

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
  • pthread_mutex_t *mutex : 초기화할 mutex
  • const pthread_mutexattr_t *attr : mutex의 특성, 기본적으로 NULL

성공시 0을 반환하고, 실패시 아래를 반환한다.

  • [EINVAL] : The value specified by attr is invalid.
  •  [ENOMEM] : The process cannot allocate enough memory to create another mutex.

 

pthread_mutex_lock & pthread_mutex_unlock

mutex 임계 구역 진입 시 그 코드 구역을 잠그고 여는 함수

한 쓰레드에서 lock을 했다면 다른 코드는 그 구역에 들어가기 위해 unlock을 할때까지 기다려야한다.

#include <pthread.h>

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

성공시 0을 반환하고, 실패시 아래를 반환한다.

  • [EINVAL] : The value specified by mutex is invalid.
  • (lock)[EDEADLK] : A deadlock would occur if the thread blocked waiting for mutex.
  • (unlock)[EPERM] : The current thread does not hold a lock on mutex.

 

728x90
300x250
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.