Skip to content

Instantly share code, notes, and snippets.

@dandrake
Created October 18, 2020 13:43
Show Gist options
  • Save dandrake/521b5619d34f98df6a93c695012c699c to your computer and use it in GitHub Desktop.
Save dandrake/521b5619d34f98df6a93c695012c699c to your computer and use it in GitHub Desktop.
pthread condition variables API, waking up multiple threads
/* Like join.c, but I want to see if multiple threads can wait on a single
condition. It looks like `pthread_cond_broadcast` is the API function for this.
What's weird is that this has some kind of race condition in it. I've seen:
* only the parent woken up
* parent and child2 woken up
* child2 woken up twice!
*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include "common.h"
#include "common_threads.h"
pthread_cond_t c = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int done = 0;
void *child(void *arg) {
printf("child sleeping for a moment\n");
sleep(1);
Mutex_lock(&m);
done = 1;
printf("child about to signal\n");
// Cond_signal(&c);
pthread_cond_broadcast(&c);
Mutex_unlock(&m);
return NULL;
}
void *child2(void *arg) {
printf("child 2 about to wait on child 1\n");
Mutex_lock(&m);
printf("child 2 got the lock\n");
while (done == 0) {
printf("child 2 about to wait\n");
Cond_wait(&c, &m); // releases lock when going to sleep
}
Mutex_unlock(&m);
printf("child 2 woke up\n");
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t p;
printf("parent: begin\n");
Pthread_create(&p, NULL, child, NULL);
Pthread_create(&p, NULL, child2, NULL);
Mutex_lock(&m);
printf("parent got the lock\n");
while (done == 0) {
printf("parent sees done == 0, about to wait\n");
Cond_wait(&c, &m); // releases lock when going to sleep
}
Mutex_unlock(&m);
printf("parent: woke up\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment