/* * Implementação com alto paralelismo, mas sujeita a starvation. */ #include #include #include #include #define N 5 #define MAX_REFEICOES 100 #define ESQ (phil_id + 1) % N #define DIR (phil_id + N - 1) % N typedef enum {T, H, E} estado_t; estado_t estado[N]; pthread_cond_t cond[N]; pthread_mutex_t mutex; int refeicoes[N], total_refeicoes; /* Considera que já adquiriu o mutex */ void exibe_mesa() { int i; for (i = 0; i < N; i++) switch (estado[N]) { case T: printf("T "); break; case H: printf("H "); break; case E: printf("E "); break; } printf("\n"); } /* Considera que já adquiriu o mutex */ void encerra_execucao() { int i; printf("Total de refeicoes: \n"); for (i = 0; i < N; i++) printf("Filosofo %d: %d\n", i, refeicoes[i]); exit(0); } /* Considera que já adquiriu o mutex */ void testa_garfos(int phil_id) { if (estado[phil_id] == H && estado[ESQ] != E && estado[DIR] != E) { estado[phil_id] = E; pthread_cond_signal(&cond[phil_id]); } } void pensa(int phil_id) { sleep(1); } void pega_garfos(int phil_id) { pthread_mutex_unlock(&mutex); estado[phil_id] = H; exibe_mesa(); testa_garfos(phil_id); } void solta_garfos(int phil_id) { } void* f_phil(void *v) { int phil_id = *(int *) v; while(1) { pensa(phil_id); pega_garfos(phil_id); come(phil_id); solta_garfos(phil_id); } } pthread_mutex_lock(&mutex); if (estado[ESQ] != E && estado[DIR] != E) estado[phil_id] = E; else pthread_cond_wait(&cond[phil_id], &mutex); /* Filosofo esta comendo */ exibe_pega_garfos_e_come(&mesa, phil_id); pthread_mutex_unlock(&mutex); sleep(5); /* Filosofo termina de comer */ pthread_mutex_lock(&mutex); estado[phil_id] = T; exibe_solta_garfos_e_pensa(&mesa, phil_id); /* Filosofo verifica se a brincadeira acabou */ refeicoes[phil_id]++; if (++total_refeicoes == MAX_REFEICOES) encerra_execucao(); /* Filosofo verifica se os seus vizinhos podem comer agora */ verifica_vizinho(ESQ); verifica_vizinho(DIR); pthread_mutex_unlock(&mutex); } return NULL; } int main() { pthread_t thr[N]; int i, phil_id[N]; inicia_mesa(&mesa, N); pthread_mutex_init(&mutex, NULL); total_refeicoes = 0; for (i = 0; i < N; i++) { pthread_cond_init(&cond[i], NULL); phil_id[i] = i; refeicoes[i] = 0; } for (i = 0; i < N; i++) pthread_create(&thr[i], NULL, f_phil, (void*) &phil_id[i]); for (i = 0; i < N; i++) pthread_join(thr[i], NULL); return 0; }