/* * Thread 0 acorda todas as threads que estiverem dormindo. */ #include #include #include #include /* Flags auxiliares */ volatile int n_threads_dormindo = 0; volatile int thr0_ja_executou = 0; pthread_cond_t cond; pthread_mutex_t mutex; void *thread_i(void* v) { int i = *(int*) v; sleep(random() % 2); pthread_mutex_lock(&mutex); if (!thr0_ja_executou) { printf("Thread %d vai dormir... \n", i); n_threads_dormindo++; pthread_cond_wait(&cond, &mutex); n_threads_dormindo--; printf("Thread %d acordou (%d estão dormindo). \n", i, n_threads_dormindo); } else printf("Thread %d não vai dormir.\n", i); pthread_mutex_unlock(&mutex); return NULL; } void *thread_0(void* v) { sleep(3); pthread_mutex_lock(&mutex); if (n_threads_dormindo > 0) { printf("Thread 0 vai acordar %d threads. \n", n_threads_dormindo); pthread_cond_broadcast(&cond); } thr0_ja_executou = 1; pthread_mutex_unlock(&mutex); return NULL; } #define N 10 int main() { pthread_t thr[N]; int i, id[N]; pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); for (i = 1; i < N; i++) { id[i] = i; pthread_create(&thr[i], NULL, thread_i, &id[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; }