/* * Segunda tentativa de implementação do algoritmo da padaria * utilizando locks e variáveis de condição. */ #include #include #include #include #define N 10 volatile int s = 0; /* Variável compartilhada */ volatile int num[N]; /* Vetor de senhas */ pthread_mutex_t mutex[N]; pthread_cond_t cond[N]; /* Retorna o valor máximo presente no vetor num */ int max() { int i, m = num[0]; for (i = 1; i < N; i++) if (m < num[i]) m = num[i]; return m; } void* f_thread(void *v) { int thr_id = *(int *)v; int i, j, m; for (i = 0; i < 10; i++) { pthread_mutex_lock(&mutex[thr_id]); m = max(); usleep(10); num[thr_id] = m + 1; /* Calcula senha */ pthread_mutex_unlock(&mutex[thr_id]); for (j = 0; j < N; j++) { pthread_mutex_lock(&mutex[j]); while (num[j] != 0 && (num[j] < num[thr_id] || (num[j] == num[thr_id] && j < thr_id))) pthread_cond_wait(&cond[j], &mutex[j]); pthread_mutex_unlock(&mutex[j]); } s = thr_id; usleep(10); printf("Thread %d, s = %d, num = %d.\n", thr_id, s, num[thr_id]); usleep(10); pthread_mutex_lock(&mutex[thr_id]); num[thr_id] = 0; /* Marca que saiu da região crítica */ pthread_cond_broadcast(&cond[thr_id]); pthread_mutex_unlock(&mutex[thr_id]); usleep(10); } return NULL; } int main() { pthread_t thr[N]; int i, id[N]; for (i = 0; i < N; i++) { num[i] = 0; pthread_mutex_init(&mutex[i], NULL); pthread_cond_init(&cond[i], NULL); } for (i = 0; i < N; i++) { id[i] = i; pthread_create(&thr[i], NULL, f_thread, &id[i]); } for (i = 0; i < N; i++) pthread_join(thr[i], NULL); for (i = 0; i < N; i++) { pthread_mutex_destroy(&mutex[i]); pthread_cond_destroy(&cond[i]); } return 0; }