スレッドが終了する前にフラグを設定する (またはイベントを通知する) ことは、競合状態です。スレッドはまだ OS に戻っているとは限らず、まだ実行中の可能性があります。
たとえば、動的ライブラリ (疑似コード) をロードするプログラムを考えてみます。
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()
これにより、スレッドが OS に戻り、実行されなくなります。