Я получаю 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 ()является проблемой, и если да, то как следует исправить мой код.