반응형
원래 해결법에서는 짝수가 왼쪽을 들고,,? 홀수가 오른쪽을 든다..? 이렇게 접근을 하게 되는데 나는 이렇게 하지 않았다.
그냥 홀수가 먼저 먹게 하고 짝수가 먼저 먹게 하였다.
헤더 파일
- info가 크게 있고 이 안에 필로들이 다 있다.
typedef struct s_philo
{
int philo_name;
int fork_left;
int fork_right;
long int thread_time;
long int last_eat;
int eat;
pthread_t thread;
pthread_mutex_t eye;
struct s_info *info;
} t_philo;
typedef struct s_info
{
int philo_number;
int time_to_die;
int time_to_eat;
int time_to_sleep;
int must_eat;
int finished_eat;
int death_flag;
long int start_time;
pthread_mutex_t count_eat;
pthread_mutex_t print;
pthread_mutex_t death_m;
pthread_mutex_t *fork_m;
pthread_mutex_t eat_mutex;
t_philo *philo;
}t_info;
main.c
int main(int argc, char **argv)
{
t_info info;
//인자값 검사
if (!(argc >= 5 && argc <= 6))
{
print_error("Wrong argc\\n");
return (1);
}
if (init(&info, argv, argc))
{
print_error("Wrong argv\\n");
return (1);
}
ft_philo_start(&info);
free_philo(&info);
}
init.c
- info구조체 안에 philo_number, time_to_die, time_to_eat, time_to_sleep 등을 초기화
- philo들을 각각 malloc 해주며 포크가 겹치는 부분이 있게 만들어준다.
int init(t_info *info, char **argv, int argc)
{
info->philo_number = atoi_while(argv[1]);
info->time_to_die = atoi_while(argv[2]);
info->time_to_eat = atoi_while(argv[3]);
info->time_to_sleep = atoi_while(argv[4]);
info->death_flag = 0;
info->must_eat = -1;
info->finished_eat = 0;
info->start_time = 0;
if (argc == 6)
info->must_eat = atoi_while(argv[5]);
if (info->philo_number <= 0 || info->time_to_die <= 0 || \\
info->time_to_eat <= 0 || info->time_to_sleep <= 0)
return (1);
if (argc == 6)
if (info->must_eat <= 0)
return (1);
if (init_mutex(info))
return (1);
if (init_philo(info))
return (1);
return (0);
}
int init_philo(t_info *info)
{
int i;
i = 0;
info->philo = malloc(sizeof(t_philo) * info->philo_number);
if (!info->philo)
return (1);
while (i < info->philo_number)
{
info->philo[i].philo_name = i + 1;
info->philo[i].fork_left = (i + 1) % info->philo_number;
info->philo[i].fork_right = i;
info->philo[i].eat = 0;
info->philo[i].thread_time = 0;
info->philo[i].info = info;
pthread_mutex_init(&info->philo[i].eye, NULL);
i++;
}
return (0);
}
int init_mutex(t_info *info)
{
int i;
pthread_mutex_init(&info->count_eat, NULL);
pthread_mutex_init(&info->print, NULL);
pthread_mutex_init(&info->death_m, NULL);
pthread_mutex_init(&info->eat_mutex, NULL);
info->fork_m = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t) \\
* info->philo_number);
if (!(info->fork_m))
return (1);
i = 0;
while (i < info->philo_number)
{
if (pthread_mutex_init(&(info->fork_m[i]), NULL))
return (1);
i++;
}
return (0);
}
ft_philo_start 함수
- pthread_create로 필로들의 쓰레드를 각각 만들어준다.
- ft_philo_check_finish는 필로들 중에 죽은 친구들이 있는지 검사하는 친구이다. 즉 모니터링이라고 보면 된다.
- action_thread에서 먹고, 자고, 생각하고를 해주면 된다.
int ft_philo_start(t_info *info)
{
int i;
i = 0;
info->start_time = time_init();
while (i < info->philo_number)
{
info->philo[i].thread_time = time_init();
pthread_create(&(info->philo[i].thread), NULL, \\
action_thread, &(info->philo[i]));
i++;
}
ft_philo_check_finish(info->philo);
i = 0;
while (i < info->philo_number)
{
pthread_join(info->philo[i].thread, NULL);
i++;
}
return (0);
}
action_thread 함수
void *action_thread(void *tmp)
{
t_philo *philo;
philo = (t_philo *)tmp;
if (philo->philo_name % 2 == 0)
usleep(1000);
pthread_mutex_lock(&(philo->info->death_m));
while (!(philo->info->death_flag))
{
pthread_mutex_unlock(&(philo->info->death_m));
if (thread_eat(philo) == 1)
return (0);
if (must_eat_count(philo) == 1)
break ;
printf_time_number(philo, "is sleeping");
ft_pass_time(philo->info->time_to_sleep, philo->info);
printf_time_number(philo, "is thinking");
pthread_mutex_lock(&(philo->info->death_m));
}
if (philo->info->must_eat != philo->eat)
pthread_mutex_unlock(&(philo->info->death_m));
return ((void *)0);
}
반응형
'42Seoul > philsopheres' 카테고리의 다른 글
philosophers c언어 함수 (0) | 2023.09.11 |
---|---|
Philosophers 데이터레이스, 교착상태, 뮤텍스 (0) | 2023.09.11 |
philsopheres 문제 정리 (0) | 2023.09.11 |