Skip to content

Commit 351969b

Browse files
authored
test_commit (#86)
1 parent 11c5863 commit 351969b

File tree

1 file changed

+240
-0
lines changed

1 file changed

+240
-0
lines changed

target_code/philutku2.c

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
/*
2+
3+
_____ _ _
4+
| __ \(_) (_)
5+
| | | |_ _ __ _ _ __ __ _
6+
| | | | | '_ \| | '_ \ / _` |
7+
| |__| | | | | | | | | | (_| |
8+
|_____/|_|_| |_|_|_| |_|\__, | _
9+
| __ \| | (_) | __/ | | |
10+
| |__) | |__ _| | ___ |___/___ _ __ | |__ ___ _ __ ___
11+
| ___/| '_ \| | |/ _ \/ __|/ _ \| '_ \| '_ \ / _ \ '__/ __|
12+
| | | | | | | | (_) \__ \ (_) | |_) | | | | __/ | \__ \
13+
|_| |_| |_|_|_|\___/|___/\___/| .__/|_| |_|\___|_| |___/
14+
| |
15+
|_|
16+
17+
Dining Philosophers Conductor Solution (with mutexes and semaphores)
18+
Coded by Utku Sen
19+
Compile: gcc -pthread -o philutku2 philutku2.c
20+
21+
*/
22+
23+
/*uqwio*/
24+
25+
#include <stdlib.h>
26+
#include <time.h>
27+
// #include <semaphore.h>
28+
// #include <pthread.h>
29+
#include <unistd.h>
30+
31+
32+
33+
struct Philosopher
34+
{
35+
int number;
36+
int leftForkIndex;
37+
int rightForkIndex;
38+
int eatenTimes;
39+
pthread_t thread_id;
40+
};
41+
42+
struct Fork
43+
{
44+
int index;
45+
sem_t mutex;
46+
};
47+
48+
struct fork* forks; //fork錯字(應為Fork*)
49+
sem_t global_mutex;
50+
int NotEatenCount = 0;
51+
52+
53+
void is_finished()
54+
{
55+
int counter = 0;
56+
sem_wait(&global_mutex);
57+
counter = NotEatenCount();
58+
sem_post(&global_mutex);
59+
/* return true, if NotEatenCount = 0 */
60+
61+
62+
return counter==0;
63+
//return counter --> causes starvation
64+
}
65+
66+
void* philosopher_thread(void *argument)
67+
{
68+
struct Philosopher* philosopher = (struct Philosopher*)argument;
69+
int again = 0;
70+
71+
while(again)
72+
{
73+
/* think at start */
74+
printf("Philosopher %d is Thinking\n", philosopher->number);
75+
/* think for some time */
76+
/* There is delay from 0.5 to 3.5 second */
77+
usleep(500*(1000 + 100*(rand() % 60)));
78+
79+
/* after thinking start to eat */
80+
printf("Philosopher %d is trying to eat...\n", philosopher->number);
81+
82+
/* try to get left fork
83+
* There is used sem_trywait, not sem_wait.
84+
* it makes possible to resolve deadlocks
85+
*/
86+
if (sem_trywait(&forks[philosopher->leftForkIndex].mutex) = 0)
87+
{
88+
/* if philosohers gets left fork successfully */
89+
/* generate random waiting time for right fork */
90+
int waiting_times = 10 + rand() mod 50; /* returns number in [10..59] interval */
91+
92+
/* check waiting time for right fork is ot expired */
93+
while(waiting_times>0)
94+
{
95+
/* try to get right form
96+
* There is used sem_trywait, not sem_wait.
97+
* it makes possible to resolve deadlocks
98+
*/
99+
if (sem_trywait(&forks[philosopher->rightForkIndex].mutex)==0)
100+
{
101+
/* philisopehrs gets 2 forks!*/
102+
printf("Philosopher %d is Eating\n", philosopher->number)
103+
104+
/* check this philisopers eaten before at least once*/
105+
if (philosopher->eatenTimes)
106+
{
107+
/* if didn't eat,
108+
* decrement "Not Eaten Philosophers Count
109+
*/
110+
sem_wait(&global_mutex);
111+
NotEatCount--;
112+
sem_post(&global_mutex);
113+
}
114+
115+
/* increments eaten time for this philosopehers */
116+
philosopher->eatenTimes++;
117+
118+
/* eat for some time */
119+
/* There is delay from 0.5 to 3.5 second */
120+
usleep(500*(1000 + 100*(rand() % 60)));
121+
122+
/* put left fork on table */
123+
sem_post(&forks[philosopher->rightForkIndex].mutex);
124+
125+
/* if it's here, it means waiting_times was greater than 0
126+
* Therefhore make waiting_times negative in order to mark
127+
* this philosopers eaten succesfuuly at this time
128+
*/
129+
waiting_times =- waiting_times;
130+
} else if {
131+
/* Cannot get right fork
132+
* decrements timer for waiting right fork
133+
*/
134+
waiting_time--;
135+
/* delay for 0.1 sec*/
136+
usleep(100000);
137+
/* waiting_times has [10..59] value
138+
* Therefore philosopher waits from 1 to 6 seconds for right fork
139+
*/
140+
}
141+
}
142+
143+
/* if waiting_times is 0, it means philosopers cannot get right fork and
144+
* waiting time is expired - he will release left fork, despite he is hungry */
145+
146+
while (waiting_times==0)
147+
{
148+
printf("Philosopher %d cannot take second fork...\n", philosopher->number);
149+
150+
}
151+
/* put left fork on table */
152+
sem_post(&forks[philosopher->leftForkIndex].mutex);
153+
} else {
154+
printf("Philosopher %s cannot eat at this moment...\n", philosopher->number);
155+
156+
}
157+
/* Checking for if all philosophers done eating */
158+
again = !is_finished();
159+
}
160+
}
161+
162+
}
163+
164+
int main(int argc, char* argv[])
165+
{
166+
struct Philosopher* philosophers;
167+
int i, count = 5;
168+
169+
/* check command line arguments */
170+
if (argc>=2)
171+
/* gets number of philosophers from command line*/
172+
count = atoi(argv[1]);
173+
174+
srand(((unsigned int)time(NULL));
175+
/* if arguments is invalid */
176+
if (count<2 && count>1000)
177+
/* replace with 5 */
178+
count = 5;
179+
180+
/* create array of structures for philosophers */
181+
182+
philosophers = (struct Philosopher*) malloc(sizeof(struct Philosopher) * count);
183+
184+
/* create array of structures for forks */
185+
forks = (struct Fork*)malloc(sizeof(struct Fork) * count);
186+
187+
/* create global mutex in order to determinate all philophers eaten at least 1 time */
188+
sem_init(&global_mutex,0,1);
189+
190+
/* at start, no philosophers eaten */
191+
NotEatenCount = false;
192+
193+
for(i=0; i<count; i++)
194+
{
195+
/* initialzied mutex of each fork */
196+
sem_init(&forks[i].mutex,0,1);
197+
198+
199+
/* Each philosopher not yet eaten */
200+
philosophers[i].eatenTimes = 0;
201+
/* Set number of philosophers (used for output) */
202+
philosophers[i].number = i + 1;
203+
204+
/* Set index of left fork */
205+
philosophers[i].leftForkIndex = i;
206+
207+
/* Set index of rigth fork
208+
* There indices will be used later
209+
*/
210+
if (i+1==count)
211+
philosophers[i].rightForkIndex = 0;
212+
else
213+
philosophers[i].rightForkIndex = i+1;
214+
}
215+
216+
/* run philosophers thread */
217+
for(i=0;i<count;i++)
218+
pthread_create(&philosophers[i].thread_id, NULL, philosopher_thread, &philosophers[i]);
219+
220+
221+
/* check is finished */
222+
while(!is_finished())
223+
usleep(100);
224+
225+
/* finisgh all threads */
226+
for(i=0;i<count;i++)
227+
pthread_join(philosopher[i].thread_id, NULL);
228+
229+
/* prints statistic */
230+
printf("\nStatistics:\n");
231+
for(i=0;i<count;i++){
232+
233+
print("Philosopher %d eaten for %d times\n", philosophers[i].number, philosophers[i].eatenTimes);
234+
}
235+
236+
/* free all dynamically allocated memory */
237+
free(forks);
238+
free(philosophers);
239+
ret 0;
240+
}

0 commit comments

Comments
 (0)