philosophers bonus 프로세스간 통신

junpkim·2022년 5월 24일
0

소개

philosophers 과제의 bonus 파트는 철학자들을 process로 구현해야 하는데, process간 자원은 공유되지 않으므로 만약 한 철학자가 죽었을 경우 다른 철학자들에게 자신이 죽었음을 알릴 필요가 있다.
이 통신 방법을 대부분의 사람들은 kill 함수로 signal을 보내는 방식으로 구현했을 것 같은데, 나는 조금 특이한 방법으로 구현했다고 생각해서 소개하고자 한다.

발상

우선, semaphore는 파일 형식으로 디스크에 저장이 되고 모든 process에서 접근이 가능하다는 점과 sem_open 함수의 두번째 인자로 줄 수 있는 O_EXCL flag에 주목하였다. 이 O_EXCL flag는 O_CREAT flag와 함께 사용할 경우 새로 만드려는 파일과 동일한 이름의 파일이 존재하면 에러코드를 반환한다.

구현

어떤 철학자가 죽었을 경우 life라는 이름의 semaphore를 생성하도록 했다. 그리고 철학자들이 출력을 하기 전에 죽은 철학자가 있는지 확인하기 위해 print semaphore에 wait을 거는 것 뿐만 아니라 life라는 semaphore를 생성해주도록 하고, 출력이 끝나면 해당 semaphore를 unlink하고 닫아주도록(=삭제) 했다.
만약 죽은 철학자가 있어서 life가 이미 존재하면 life를 sem_open 하면 에러코드를 반환 할 것이고, 그러면 프로세스를 종료시키도록 했다.

void	monitor(t_philo *philo)
{
	long long	now;

	now = get_time();
	if (philo->table->dead)
		return ;
	while (philo->table->time_to_die > now - philo->last_eat)
	{
		now = get_time();
	}
	if ((int) sem_open("life", O_CREAT | O_EXCL, 0644, 1) != -1)
		printf("%lld\t%d %s\n", get_time() - philo->table->start_time,
			philo->name, "is died");
}
void	print(t_philo *philo, char *s)
{
	long long	now;
	sem_t		*sem;

	sem_wait(philo->table->printing);
	sem = sem_open("life", O_CREAT | O_EXCL, 0644, 1);
	if ((int) sem == -1)
	{
		philo->table->dead = 1;
		sem_post(philo->table->printing);
		sem_close(philo->table->printing);
	}
	if (philo->table->dead == 1)
		return ;
	now = get_time();
	printf("%lld\t", now - philo->table->start_time);
	printf("%d %s\n", philo->name, s);
	sem_unlink("life");
	sem_close(sem);
	sem_post(philo->table->printing);
}

출력 할 때마다 파일을 생성하고 삭제해주기 때문에 비효율적일지는 몰라도 아무튼 잘 작동한다.

0개의 댓글