recently, I noticed that my code randomly causes Segmentation Fault errors. But I think that my code is pretty simple so far and I cant figure out wh
pthread_cond_wait()
is allowed to wake up spuriously, so you have to re-test the condition itself after every wakeup. This could be causing your problem - if the main thread wakes up spuriously before thread::terminated_thread_id
has been set, it'll pass an invalid thread id to pthread_join()
.
There's also another problem in your code - there's no guarantee that the signalled thread will be the next to wake up after the mutex is unlocked, so it's possible for two threads to call thread::Exit()
in quick succession, with the main thread not running until after the second exiting thread has unlocked the mutex. In this case you won't ever call pthread_join()
on the first thread.
Something like this should fix those problems:
namespace thread {
int terminate_thread_set = 0;
pthread_mutex_t terminate_thread = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t terminate_thread_set_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t terminate_thread_unset_cond = PTHREAD_COND_INITIALIZER;
/* ... */
inline void Exit(void* value)
{
pthread_mutex_lock(&thread::terminate_thread);
while (thread::terminate_thread_set)
pthread_cond_wait(&thread::terminate_thread_unset_cond);
thread::terminated_thread_id = pthread_self();
thread::terminate_thread_set = 1;
pthread_cond_signal(&thread::terminate_thread_set_cond);
pthread_mutex_unlock(&thread::terminate_thread);
pthread_exit(value);
}
}
and in main
:
pthread_mutex_lock(&thread::terminate_thread);
/* ... */
while(thread::total_thread_count > 0) {
while (!thread::terminate_thread_set)
pthread_cond_wait(&thread::terminate_thread_set_cond, &thread::terminate_thread);
thread::terminate_thread_set = 0;
pthread_join(thread::terminated_thread_id, NULL);
pthread_cond_signal(&thread::terminate_thread_unset_cond);
...
}
pthread_mutex_unlock(&thread::terminate_thread);
That's not to say that you don't have other issues, of course.