-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphilosophers_atk_circular.c
99 lines (84 loc) · 2.11 KB
/
philosophers_atk_circular.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//gcc -Wall -lpthread
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUMFILO 5
pthread_t filosofo [NUMFILO] ; // threads filosofos
sem_t hashi [NUMFILO] ; // um semaforo para cada palito (iniciam em 1)
// espaços para separar as colunas de impressão
char *space[] = {"", "\t", "\t\t", "\t\t\t", "\t\t\t\t" } ;
// espera um tempo aleatório entre 0 e n segundos (float)
void espera (int n)
{
sleep (random() % n) ; // pausa entre 0 e n segundos (inteiro)
usleep (random() % 1000000) ; // pausa entre 0 e 1 segundo (float)
}
// filósofo comendo
void come (int f)
{
printf ("%sCOMENDO\n", space[f]) ;
// espera (2) ;
}
// filósofo meditando
void medita (int f)
{
printf ("%smeditando\n", space[f]) ;
// espera (2) ;
}
// pega o hashi
void pega_hashi (int f, int h)
{
printf ("%squer h%d\n", space[f], h) ;
sem_wait (&hashi [h]) ;
printf ("%spegou h%d\n", space[f], h) ;
}
// larga o hashi
void larga_hashi (int f, int h)
{
printf ("%slarga h%d\n", space[f], h) ;
sem_post (&hashi [h]) ;
}
// corpo da thread filosofo
void *threadFilosofo (void *arg)
{
int i = (long int) arg ;
while (1)
{
medita (i) ;
if(i/2 == 0){ // filo enumerado par pega sempre hashi i primeiro
pega_hashi (i, i) ;
pega_hashi (i, (i+1) % NUMFILO) ;
} else { // filo enumerado impar pega sempre hashi i+1 primeiro
pega_hashi (i, (i+1) % NUMFILO) ;
pega_hashi (i, i) ;
}
come (i) ;
larga_hashi (i, i) ; // a ordem em que se larga não importa
larga_hashi (i, (i+1) % NUMFILO) ;
}
pthread_exit (NULL) ;
}
// programa principal
int main (int argc, char *argv[])
{
long i, status ;
// para o printf não se confundir com a threads
setvbuf (stdout, 0, _IONBF, 0) ;
// inicia os hashis
for(i=0; i<NUMFILO; i++)
sem_init (&hashi[i], 0, 1) ;
// inicia os filosofos
for(i=0; i<NUMFILO; i++)
{
status = pthread_create (&filosofo[i], NULL, threadFilosofo, (void *) i) ;
if (status)
{
perror ("pthread_create") ;
exit (1) ;
}
}
// a main encerra aqui
pthread_exit (NULL) ;
}