/* Compile with cc -Og -o thread_sleeps -pthread thread_sleeps.c */ #include #include #include #include int main(int argc, char *argv[]); void* sender(void*); void* receiver(void*); static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t sent = PTHREAD_COND_INITIALIZER; int n_sends = 0; #define NPASSES 20 int main(int argc, char *argv[]) { pthread_t sender_tid; pthread_t receiver_tid; if (pthread_create (&sender_tid, NULL, sender, NULL) != 0) { fprintf(stderr, "Couldn't create sender thread\n"); return 1; } if (pthread_create (&receiver_tid, NULL, receiver, NULL) != 0) { fprintf(stderr, "Couldn't create receiver thread\n"); return 1; } if (pthread_join (sender_tid, NULL) != 0) { fprintf(stderr, "Couldn't join with sender thread\n"); return 1; } if (pthread_join (receiver_tid, NULL) != 0) { fprintf(stderr, "Couldn't join with receiver thread\n"); return 1; } return 0; } /* * The sender sends one signal per second, bumping n_sends each time. */ void* sender(void* data) { int i; for (i = 0; i < NPASSES; i++) { sleep(1); printf("Sender sent %d time(s)\n", i + 1); pthread_mutex_lock(&mutex); ++n_sends; pthread_cond_signal(&sent); pthread_mutex_unlock(&mutex); } return NULL; } /* * The receiver counts the number of sends it has seen. After * receiving a message, it might sleep up to 3 seconds. */ void* receiver(void* data) { int messages_seen = 0; while (1) { if (messages_seen >= NPASSES) { printf(" Receiver saw %d messages\n", messages_seen); return NULL; } pthread_mutex_lock(&mutex); while (n_sends == messages_seen) { pthread_cond_wait(&sent, &mutex); } pthread_mutex_unlock(&mutex); ++messages_seen; printf(" Receiver saw %d messages...", messages_seen); if (n_sends < messages_seen) { printf("Oops! Saw more messages than sent!\n"); exit(1); } else if (n_sends == messages_seen) { int sleep_time = random() % 4; if (sleep_time == 0) printf("but not sleeping\n"); else { printf("sleeping %d second(s)\n", sleep_time); sleep(sleep_time); } } else printf("continuing immediately\n"); } }