/* * Controle da região crítica por alternância simples. * Código para N threads. */ #include #include #include #include #include #include #include #include #include #define N 10 volatile int s = 0; /* Variável compartilhada */ volatile int vez = 0; /* Indica de qual thread é a vez de entrar na região crítica */ volatile int vvez[N]; /* Retorna -1 se o futex não bloqueou e 0 caso contrário */ int futex_wait(void *addr, int val1) { return syscall(SYS_futex, addr, FUTEX_WAIT, val1, NULL, NULL, 0); } /* Retorna o número de threads que foram acordadas */ int futex_wake(void *addr, int n) { return syscall(SYS_futex, addr, FUTEX_WAKE, n, NULL, NULL, 0); } void* f_thread(void *v) { int thr_id = *(int*)v; int proximo = (thr_id + 1)%N; int i, vez_local; for (i = 0; i < 5; i++) { while (vvez[thr_id] == 0) futex_wait(&vvez[thr_id], 0); /* vez_local = vez; if (vez_local != thr_id) futex_wait(&vez, vez_local); */ s = thr_id; printf("Thread %d, s = %d.\n", thr_id, s); vvez[thr_id] = 0; vvez[proximo] = 1; futex_wake(&vvez[proximo], 1); /* vez = (thr_id + 1)%N; Passa a vez para a outra thread */ } return NULL; } int main() { pthread_t thr[N]; int id[N], i; vvez[0] = 1; for (i = 1; i < N; i++) vvez[i] = 0; 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); return 0; }