/* * Problema do barbeiro dorminhoco. */ /* * Modificado por Marília Felippe Chiozo para o projeto de implementação. A * cadeira do barbeiro é representada por / \, o barbeiro dormindo por ZZZ, * o barbeiro acordado por B, as cadeiras da fila de espera por | |, os * clientes por seus números (avançando sobre as letras minúsculas caso o * (número de clientes seja maior que 10), e a porta da barbearia (onde * aparecem os clientes que não conseguem entrar) por --- ---. Esta * implementação reserva um dígito só por cliente, precisando ser modificada * caso se queira mais de um dígito. */ #include #include #include #include #include #include #include #define N_CLIENTES 12 #define N_CADEIRAS 4 #define DRAWING_STR "%s\n\n%s\n\n%s\n_____________________________\n" sem_t sem_cadeiras; sem_t sem_cad_barbeiro; sem_t sem_cabelo_cortado; sem_t sem_cliente_cadeira; pthread_mutex_t screen; char line1[] = " ZZZ/ \\ "; /* Barber's chair. */ char line2[2 + 4 * N_CADEIRAS]; /* Waiting chairs. */ char line3[] = "--- ---"; /* Barber shop door. */ char idmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; void* f_barbeiro(void* v) { while (1) { /* Draws the barber asleep. */ pthread_mutex_lock(&screen); line1[5] = line1[6] = line1[7] = 'Z'; printf(DRAWING_STR, line1, line2, line3); pthread_mutex_unlock(&screen); /* Waits for a client. */ sem_wait(&sem_cliente_cadeira); /* Draws the barber awake. */ pthread_mutex_lock(&screen); line1[5] = line1[6] = ' '; line1[7] = 'B'; printf(DRAWING_STR, line1, line2, line3); pthread_mutex_unlock(&screen); sleep(2); sem_post(&sem_cabelo_cortado); } return NULL; } void* f_cliente(void* v) { int i; int id = *((int*) v); sleep(id % 3); if (sem_trywait(&sem_cadeiras) == 0) { /* Draws the client in the first free waiting chair he can find. */ pthread_mutex_lock(&screen); for (i = 0; i < N_CADEIRAS; i++) if (line2[2 + 4 * i] == ' ') break; line2[2 + 4 * i] = idmap[id]; printf(DRAWING_STR, line1, line2, line3); pthread_mutex_unlock(&screen); /* Waits for the barber's chair to be free. */ sem_wait(&sem_cad_barbeiro); /* Draws the client in the barber's chair. */ pthread_mutex_lock(&screen); line1[10] = idmap[id]; line2[2 + 4 * i] = ' '; printf(DRAWING_STR, line1, line2, line3); pthread_mutex_unlock(&screen); /* Signals others waiting on the resources and waits for the haircut. */ sem_post(&sem_cliente_cadeira); sem_post(&sem_cadeiras); sem_wait(&sem_cabelo_cortado); /* Signals others waiting on the barber's chair. */ sem_post(&sem_cad_barbeiro); /* Erases the client from the drawing. */ pthread_mutex_lock(&screen); if (line1[10] == idmap[id]) { line1[10] = ' '; printf(DRAWING_STR, line1, line2, line3); } pthread_mutex_unlock(&screen); } else { pthread_mutex_lock(&screen); line3[4] = idmap[id]; printf(DRAWING_STR, line1, line2, line3); line3[4] = ' '; pthread_mutex_unlock(&screen); } return NULL; } int main() { pthread_t thr_clientes[N_CLIENTES], thr_barbeiro; int i, id[N_CLIENTES]; assert(N_CLIENTES <= 36); /* pthreads initialization stuff. */ sem_init(&sem_cadeiras, 0, 5); sem_init(&sem_cad_barbeiro, 0, 1); sem_init(&sem_cliente_cadeira, 0, 0); sem_init(&sem_cabelo_cortado, 0, 0); pthread_mutex_init(&screen, NULL); /* Initializes the string with the chairs. */ line2[0] = '|'; for (i = 0; i < N_CADEIRAS; i++) strcpy((line2 + 1 + 4 * i), " |"); /* Client threads creation. */ for (i = 0; i < N_CLIENTES; i++) { id[i] = i; pthread_create(&thr_clientes[i], NULL, f_cliente, (void*) &id[i]); } /* Barber thread creation. */ pthread_create(&thr_barbeiro, NULL, f_barbeiro, NULL); /* Waits for client threads to finish. */ for (i = 0; i < N_CLIENTES; i++) pthread_join(thr_clientes[i], NULL); /* Barbeiro é assassinado */ return 0; }