Если поток устанавливает флаг (или сигнализирует о событии) перед выходом, это состояние гонки. Поток еще не обязательно вернулся в ОС и может все еще выполняться.
Например, рассмотрим программу, загружающую динамическую библиотеку (псевдокод):
lib = loadLibrary("someLibrary");
fun = getFunction("someFunction");
fun();
unloadLibrary(lib);
И давайте предположим, что эта библиотека использует ваш поток:
void someFunction() {
volatile bool finished_flag = false;
thrd = new boost::thread(boost::bind(&myclass::mymethod, this, &finished_flag);
while(!finished_flag) { // ignore the polling loop, it's besides the point
sleep();
}
delete thrd;
}
void myclass::mymethod() {
// do stuff
finished_flag = true;
}
Когда myclass::mymethod()
устанавливает finished_flag
в true
, myclass::mymethod()
еще не вернулся. По крайней мере, он все еще должен выполнить какую-то инструкцию «возврата» (если не больше: деструкторы, управление обработчиками исключений и т. д.). Если поток, выполняющий myclass::mymethod()
, будет вытеснен до этого момента, someFunction()
вернется к вызывающей программе, и вызывающая программа выгрузит библиотеку. Когда поток, выполняющий myclass::mymethod()
, снова запускается по расписанию, адрес, содержащий инструкцию «return», становится недействительным, и программа аварийно завершает работу.
Решением для someFunction()
будет вызов thrd->join()
перед возвратом. Это гарантирует, что поток вернулся в ОС и больше не выполняется.
person
bk1e
schedule
16.09.2008