pthread_cond_wait: random segmentation fault

后端 未结 3 871
[愿得一人]
[愿得一人] 2021-01-25 03:07

Update 3

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

3条回答
  •  梦毁少年i
    2021-01-25 03:49

    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.

提交回复
热议问题