Почему pthread _exit ()в редких случаях вызывает SEGV при вызове после pthread _detach ()?

Я получаю SEGV в C++, который я не могу легко воспроизвести (это происходит примерно в одном из 100 000 тестовых прогонов )при моем вызове pthread_join(), когда мое приложение закрывается. Я проверил значение errno, и оно равно нулю. Это работает на Centos v4.

При каких условиях pthread_join()получит SEGV? Это может быть своего рода состоянием гонки, поскольку оно встречается крайне редко. Один человек предлагает мне не вызывать pthread _detach ()и pthread _exit (), но я не понимаю, почему.

Моя первая рабочая гипотеза заключалась в том, что pthread_join()вызывается, когда pthread_exit()все еще выполняется в другом потоке, и что это каким-то образом приводит к SEGV, но многие утверждали, что это не проблема.

Неудачный код, получающий SEGV в основном потоке во время выхода из приложения, выглядит примерно так (с проверкой кода возврата ошибки для краткости):

// During application startup, this function is called to create the child thread:

return_val = pthread_create(&_threadId, &attr,
                            (void *(*)(void *))initialize,
                            (void *)this);

// Apparently this next line is the issue:
return_val = pthread_detach(_threadId);

// Later during exit the following code is executed in the main thread:

// This main thread waits for the child thread exit request to finish:

// Release condition so child thread will exit:
releaseCond(mtx(), startCond(), &startCount);

// Wait until the child thread is done exiting so we don't delete memory it is
// using while it is shutting down.
waitOnCond(mtx(), endCond(), &endCount, 0);
// The above wait completes at the point that the child thread is about
// to call pthread_exit().

// It is unspecified whether a thread that has exited but remains unjoined
// counts against {PTHREAD_THREADS_MAX}, hence we must do pthread_join() to
// avoid possibly leaking the threads we destroy.
pthread_join(_threadId, NULL); // SEGV in here!!!

Дочерний поток, который объединяется при выходе, выполняет следующий код, который начинается в точке выше, где releaseCond()вызывается в основном потоке:

// Wait for main thread to tell us to exit:
waitOnCond(mtx(), startCond(), &startCount);

// Tell the main thread we are done so it will do pthread_join():
releaseCond(mtx(), endCond(), &endCount);
// At this point the main thread could call pthread_join() while we 
// call pthread_exit().

pthread_exit(NULL);

Казалось, что поток появился правильно, и при его создании во время запуска приложения не было выдано никаких кодов ошибок, и поток правильно выполнил свою задачу, что заняло около пяти секунд до выхода из приложения.

Что может вызвать появление этого редкого SEGV и как я могу защититься от него. Одно утверждение состоит в том, что мой вызов pthread _detach ()является проблемой, и если да, то как следует исправить мой код.

5
задан WilliamKF 12 July 2012 в 02:12
поделиться