Philosophers
Overview
๊ณผ์ ๋ฅผ ํ๊ธฐ ์ ์์์ผ ํ ๊ฒ! :
- ํ๋ ์ด์์ ์ฒ ํ์๊ฐ ๋ฅ๊ทผ ํ ์ด๋ธ์ ์์ ๊ฐ์ด๋ฐ ์๋ ์คํ๊ฒํฐ๋ฅผ ๋จน์
- ์ฒ ํ์๋ eat, think, sleep ์ค ํ๋์ ์ํ๋ฅผ ์ทจํ๊ณ ์์
- ์ฒ ํ์์ ์ ๋งํผ ํฌํฌ๊ฐ ์์. ๊ผญ ์์์ผ๋ก ํฌํฌ ๋๊ฐ๋ฅผ ์ก๊ณ ๋จน์ด์ผ ํ๋โฆ
- ์ฒ ํ์๊ฐ eating์ ๋๋ด๋ฉด sleeping ์์, ์ผ์ด๋๋ฉด thinking ํจ. ์ด ์๋ฎฌ๋ ์ด์ ์ ์ฒ ํ์๊ฐ ๊ตถ์ด ์ฃฝ์ผ๋ฉด ์ข ๋ฃ
- ๋ชจ๋ ์ฒ ํ์๋ ๋จน์ด์ผ ํ๊ณ ๊ตถ์ผ๋ฉด ์๋ผ!
- ์ฒ ํ์๋ ์๋ก ์๊ธฐํ์ง ์์, ์๋ก ์ฃฝ์ ์๊ธฐ์ ์๋ค๋ ๊ฒ๋ ๋ชจ๋ฆ
- ์ฒ ํ์๊ฐ ์ฃฝ๋ ๊ฒ์ ํผํ์..
Global rules
์ ์ญ ๋ณ์ ๊ธ์ง
ํ๋ก๊ทธ๋จ์ด ์ธ์๋ก ๋ฐ๋ ๊ฒ :
- number_of_philosophers : ์ฒ ํ์ ์ == ํฌํฌ ๊ฐ์
- time_to_die(๋จ์:ms) : ์ด ์๊ฐ๋งํผ ๋ฐฅ์ ๋ชป๋จน์ผ๋ฉด ์ฃฝ์
- time_to_eat (ms) : ๋จน๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ (๋จน์ ๋ ํฌํฌ๋ ๊ผญ ๋๊ฐ์ฉ ์ด๋โฆ
์๊ทธ๋ฌ๋๊ฒจ๋์ฒด) - time_to_sleep (ms) : ์๋๋ฐ ๊ฑธ๋ฆฌ๋ ์๊ฐ
- number_of_times_each_philosopher_must_eat (optional argument) : ๋ชจ๋ ์ฒ ํ์๊ฐ ์ฃผ์ด์ง ํ์ ์ด์ ๋ฐฅ์ ๋จน์ผ๋ฉด ์๋ฎฌ๋ ์ด์ ์ข ๋ฃ. ์ด ์ธ์๊ฐ ์๋ค๋ฉด ์ฒ ํ์๊ฐ ์ฃฝ์ ๋ ์๋ฎฌ๋ ์ด์ ์ด ์ข ๋ฃํจ
๊ฐ ์ฒ ํ์๋ค์ 1 ~ n ์ ๋ฒํธ๊ฐ ๋งค๊ฒจ์ง. k={1โคkโคn}์ผ๋, k๋ฒ ์ฒ ํ์๋ k-1๊ณผ k+1 ๋ฒ ์ฒ ํ์ ์ฌ์ด์ ์์
ํ๋ก๊ทธ๋จ์ ๋ก๊ทธ:
์ฒ ํ์์ ์ํ ๋ณํ๋ ์๋์ ๊ฐ์ ํ์์ด์ด์ผ ํจ
timestamp_in_ms X has taken a fork
timestamp_in_ms X is eating
timestamp_in_ms X is sleeping
timestamp_in_ms X is thinking
timestamp_in_ms X died
timestamp_in_ms๋ ํ์ฌ miliseconds, X๋ ์ฒ ํ์ ๋ฒํธ*
Mendatory part
mandatory part rule
- ๊ฐ ์ฒ ํ์๋ ์ค๋ ๋์
- ๋ ์ฒ ํ์ ์ฌ์ด์ ํฌํฌ ํ๋๊ฐ ์กด์ฌ. ์ฒ ํ์๊ฐ ํ๋ช ์ด๋ผ๋ฉด ํฌํฌ๋ ํ๊ฐ(์ฃฝ์)
- ํฌํฌ ์ํ๋ฅผ ๋ฎคํ ์ค๋ก ๋ณดํธํ๊ธฐ
Thread
: ํ๋ก์ธ์ค ๋ด์์ ์คํ๋๋ ์ฌ๋ฌ ํ๋ฆ์ ๋จ์
- ์ค๋ ๋๋ ํ๋ก์ธ์ค ๋ด์์ stack๋ง ๋ฐ๋ก ํ ๋น๋ฐ๊ณ code, data, heap ์์ญ์ ๊ณต์ ํ๋ค.
- ๋ฉํฐ ํ๋ก์ธ์ค๋ณด๋ค ๋ฉํฐ ์ค๋ ๋ฉ์ด context switching ๋น์ฉ์ด ์ ๋ค.
- [๋๊ธฐํ] ๋ฌธ์ ๋ฅผ ์ฃผ์ํด์ผํจ
Synchronization (๋๊ธฐํ)
- ๋ค์ค ํ๋ก์ธ์ค ํน์ ๋ค์ค ์ค๋ ๋๊ฐ ํ๋์ ์์์ ์ ๊ทผํ ๊ฒฝ์ฐ ๋๊ธฐํ ๋ฌธ์ ๋ฐ์
mandatory ํ์ฉ ํจ์ ์ค๋ช
pthread.h์ ํจ์๋ค์ ์ปดํ์ผ ํ ๋, -lpthread
ํ๋๊ทธ๋ฅผ ์ฌ์ฉํด์ผ ํจ
pthread_create
: thread๋ฅผ ์์ฑint pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
return ๊ฐ
: ์ฑ๊ณต์ ์ผ๋ก pthread ๊ฐ ๋ง๋ค์ด์ง ๊ฒฝ์ฐ 0์ ๋ฐํํ๊ณ thread์ ์๋ณ์๋ฅผ ๋ด์์ค*thread
: thread์ ์๋ณ์*attr
: thread์ ์์ฑ (NULL๋ก ๋ฃ์ผ๋ฉด default ์ค์ ์ผ๋ก)*start_routine
: thread๊ฐ ์คํํ ํจ์ ํฌ์ธํฐ*arg
: start_routine์ ๋ค์ด๊ฐ ์ธ์pthread_join
: ์ค๋ ๋๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆผint pthread_join(pthread_t thread, void **value_ptr);
return ๊ฐ
: ์ฑ๊ณต์ 0, ์คํจ์ ์ค๋ฅ์ฝ๋void **value_ptr
: thread์ return valuepthread_detach
: pthread๋ฅผ ๋ถ๋ชจ pthread๋ก๋ถํฐ ๋ ๋ฆฝ์ํดint pthread_detach(pthread_t thread);
return ๊ฐ
: ์ฑ๊ณต ์ 0, ์ค๋ฅ์ ์ค๋ฅ์ฝ๋thread ์ฌ์ฉ ์ฐ์ต
#include <pthread.h> #include <stdio.h> #include <unistd.h> void *routine1(void *arg) { int num = *(int *)arg; while (num < 5) { printf("I'm t1! %d\n", num); usleep(30); num++; } printf("t1 finished!\n"); *(int *)arg = num; return (NULL); } void *routine2(void *arg) { int num = *(int *)arg; while (num < 5) { printf("I'm t2! %d\n", num); usleep(30); num++; } printf("t2 finished!\n"); *(int *)arg = num; return (NULL); } int main(void) { pthread_t t1; pthread_t t2; int arg1 = 1; int arg2 = 1; pthread_create(&t1, NULL, routine1, (void *)&arg1); pthread_create(&t2, NULL, routine2, (void *)&arg2); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("t1 : %d, t2 : %d \n", arg1, arg2); return (0); }
โ> ์ถ๋ ฅ๊ฒฐ๊ณผ
kimjiyoon@gimjiyun-ui-MacBookPro 42Seoul % !. ./a.out I'm t1! 1 I'm t2! 1 I'm t1! 2 I'm t2! 2 I'm t1! 3 I'm t2! 3 I'm t1! 4 I'm t2! 4 t1 finished! t2 finished! t1 : 5, t2 : 5
pthread_mutex_init
: mutex ์ด๊ธฐํint pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutex_attr *attr);
pthread_mutex_destroy
: mutex ํ๊ธฐ or ์ด๊ธฐํ ๋๊ธฐ ์ ์ผ๋ก ๋๋ฆฌ๊ธฐint pthread_mutex_destroy(pthread_mutex_t *mutex);
mutex๋ฅผ destroyํ๊ณ init์ผ๋ก ๋ค์ ์ด๊ธฐํ ํด์ค ์ ์์
pthread_mutex_lock
: mutex ์ ๊ธpthread_mutex_unlock
: mutex ์ ๊ธ ํด์ int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
'๐ฐ42์์ธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[42์์ธ] ๋ณธ๊ณผ์ ํ๊ธฐ Born2Code!๐ (0) | 2022.01.04 |
---|---|
[42์์ธ] 5๊ธฐ 1์ฐจ ๋ผํผ์ ํ๊ธฐ (0) | 2022.01.04 |
[42์์ธ] 5์ฐจ ์ฒดํฌ์ธ๋ฏธํ ์ ์ฒญ ๊ฟํ! (0) | 2021.06.25 |
[42์์ธ] ์จ๋ผ์ธ ํ ์คํธ ํ๊ธฐ! >_< (0) | 2021.06.19 |