/* * Modificação do algoritmo da padaria para atendimento de filas * com prioridades diferentes. */ #include #include #include #include #define N 10 /* Número de threads não prioritárias*/ #define N_VEZES 10 /* Número de acessos por thread não prioritária à região crítica */ #define M 3 /* Número de threads prioritárias*/ #define M_VEZES 4 /* Número de acessos por thread prioritária à região crítica */ volatile int s = 0; /* Variável compartilhada */ /* Vetores de controle para threads não prioritárias */ volatile int num[N]; volatile int esc[N]; /* Vetores de controle para threads prioritárias */ volatile int num_pri[M]; volatile int esc_pri[M]; /* Variáveis de controle para algoritmo do desempate */ #define PRI 0 #define NAO_PRI 1 int vez; int interesse[2]; /* Retorna o valor máximo presente em um vetor de k posições */ int max_vet(volatile int vet[], int k) { int i, m = vet[0]; for (i = 1; i < k; i++) if (m < vet[i]) m = vet[i]; return m; } /* Função executada pelas threads não prioritárias */ void* f_thread(void *v) { int thr_id = *(int *)v; int i, j; for (i = 0; i < N_VEZES; i++) { esc[thr_id] = 1; num[thr_id] = max_vet(num, N) + 1; /* Calcula senha */ esc[thr_id] = 0; for (j = 0; j < N; j++) { while (esc [j]) ; while (num[j] != 0 && (num[j] < num[thr_id] || (num[j] == num[thr_id] && j < thr_id))); } interesse[NAO_PRI] = 1; vez = NAO_PRI; while (vez == NAO_PRI && interesse[PRI]); s = thr_id; sleep(1); printf("Thread não prioritária %d, s = %d.\n", thr_id, s); interesse[NAO_PRI] = 0; num[thr_id] = 0; /* Marca que saiu da região crítica */ sleep(1); } return NULL; } int prioritaria_esperando(int thr_id) { int i; for (i = 0; i < M; i++) if (i != thr_id && num_pri[i] > 0) return 1; return 0; } /* Função executada pelas threads prioritárias */ void* f_thread_pri(void *v) { int thr_id = *(int *)v; int i, j; for (i = 0; i < M_VEZES; i++) { esc_pri[thr_id] = 1; num_pri[thr_id] = max_vet(num_pri, M) + 1; /* Calcula senha */ esc_pri[thr_id] = 0; for (j = 0; j < M; j++) { while (esc_pri [j]) ; while (num_pri[j] != 0 && (num_pri[j] < num_pri[thr_id] || (num_pri[j] == num_pri[thr_id] && j < thr_id))); } if (!interesse[PRI]) { interesse[PRI] = 1; vez = PRI; while (vez == PRI && interesse[NAO_PRI]); } s = thr_id; sleep(1); printf("Thread prioritária %d, s = %d.\n", thr_id, s); if (!prioritaria_esperando(thr_id)) interesse[PRI] = 0; num_pri[thr_id] = 0; /* Marca que saiu da região crítica */ sleep(1); } return NULL; } int main() { pthread_t thr[N], thr_pri[M]; int i, id[N], id_pri[M]; for (i = 0; i < N; i++) num[i] = 0; for (i = 0; i < M; i++) num_pri[i] = 0; for (i = 0; i < N; i++) { id[i] = i; pthread_create(&thr[i], NULL, f_thread, &id[i]); } sleep(3); for (i = 0; i < M; i++) { id_pri[i] = i; pthread_create(&thr_pri[i], NULL, f_thread_pri, &id_pri[i]); } for (i = 0; i < N; i++) pthread_join(thr[i], NULL); for (i = 0; i < M; i++) pthread_join(thr_pri[i], NULL); return 0; }