I am having a problem synchronizing the main thread with a recently launched child thread.
What I want to do:
- the main thread creates a new child thread and blocks
- the child thread starts and initializes (it may take some time)
- After initializing the child thread, the main thread continues (and the two threads execute in parallel)
My first attempt was something like this:
typedef struct threaddata_ { int running; } threaddata_t; void*child_thread(void*arg) { threaddata_t*x=(threaddata_t)arg; x->running=1; return 0; } void start_thread(void) { threaddata_t*x=(threaddata_t*)malloc(sizeof(threaddata_t)); x->running=0; int result=pthread_create(&threadid, 0, child_thread, &running); while(!x->running) usleep(100); }
Now I didn’t like it at all, because it makes the main stream sleep, possibly for a longer period than necessary. So I made a second attempt using the mutual access conditions and conditions
typedef struct threaddata_ { pthread_mutex_t x_mutex; pthread_cond_t x_cond; } threaddata_t; void*child_thread(void*arg) { threaddata_t*x=(threaddata_t)arg; pthread_cond_signal(&x->x_cond); return 0; } void start_thread(void) { threaddata_t*x=(threaddata_t*)malloc(sizeof(threaddata_t)); pthread_mutex_init(&x->x_mutex, 0); pthread_cond_init (&x->x_cond , 0); pthread_mutex_lock(&x->x_mutex); int result=pthread_create(&threadid, 0, child_thread, &running); if(!result)pthread_cond_wait(&x->x_cond, &x->x_mutex); pthread_mutex_unlock(&x->x_mutex); }
This seemed more reasonable than the first attempt (using the right signals, rather than rolling my own wait loop) until I found that this included the race condition: If the child thread completed initialization fast enough (before the main thread waits for the condition) , it will block the main thread.
I suppose my case is not so unusual, so there should be a very simple solution, but I do not see it right now.
source share