/* * Thread 0 acorda todas as threads, mas uma delas volta a dormir. */ #include #include #include #include volatile int s = 0; pthread_cond_t cond; pthread_mutex_t mutex; int preciso_esperar(int i) { return (s >= 0 || s == -i); } void marca_thread_i_vai_dormir(int i) { if (s >= 0) s = i; } void *thread_i(void* v) { int i = (int) v; /* sleep(random() % 5); */ pthread_mutex_lock(&mutex); while (preciso_esperar(i)) { printf("Thread %d vai esperar... \n", i); marca_thread_i_vai_dormir(i); pthread_cond_wait(&cond, &mutex); printf("Thread %d acordou... \n", i); } pthread_mutex_unlock(&mutex); return NULL; } int devo_acordar_alguma_thread() { return (s > 0); } void marca_thread_0_ja_executou() { s = -s; } void *thread_0(void* v) { /* sleep(2); */ pthread_mutex_lock(&mutex); if (devo_acordar_alguma_thread()) { printf("Thread 0 vai acordar todas as threads... \n"); pthread_cond_broadcast(&cond); } marca_thread_0_ja_executou(); pthread_mutex_unlock(&mutex); return NULL; } #define N 5 int main() { pthread_t thr[N]; int i; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); for (i = 1; i < N; i++) pthread_create(&thr[i], NULL, thread_i, (void *) i); pthread_create(&thr[0], NULL, thread_0, NULL); for (i = 1; i < N; i++) pthread_join(thr[i], NULL); pthread_join(thr[0], NULL); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0; }