ワーカー スレッドで割り込みをキャッチできません。ここには多数のブーストスレッド割り込み投稿がありますが、それらはばかげた間違い (私の質問もそうだと確信しています)、または役に立たなかったもののようです
私の例では、ワーカー スレッドを作成するメイン スレッドがあります。メイン スレッドは、ワーカー スレッドが while ループ内にある間、ユーザーが Enter キーを押すのを待機し、1 秒間隔でスリープします。ユーザーが Enter キーを押すと、メイン スレッドがワーカー スレッドに割り込み、join を呼び出します。ワーカー スレッドは、boost::this_thread::sleep_for(sec) で thread_interrupted 例外をスローする必要があります。これをキャッチしてから、ワーカー関数を終了する必要があります。これにより、メイン スレッドが続行され、プログラムが終了します。
#define BOOST_THREAD_USE_LIB 1
#define BOOST_SYSTEM_NO_DEPRECATED 1
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
#include <boost/thread.hpp>
#include <boost/chrono/include.hpp>
#include <boost/chrono/duration.hpp>
#include <iostream>
using namespace std;
void ThreadFunctionSleep()
{
cout << boost::this_thread::get_id() << " worker thread " << endl;
int counter = 0;
while(1)
{
cout << boost::this_thread::get_id() << " thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
boost::chrono::seconds sec(1);
boost::this_thread::sleep_for(sec);
}
catch(boost::thread_interrupted&)
{
cout << boost::this_thread::get_id() << " Thread is stopped in ThreadFunction " << endl;
return;
}
catch ( boost::thread_resource_error &)
{
cout << boost::this_thread::get_id() << " boost thread_resource_error" << endl;
return;
}
catch(...)
{
cout << boost::this_thread::get_id() << " worker func other" << endl;
return;
}
}
}
int main()
{
std::cout << boost::this_thread::get_id() << " main thread " << std::endl;
// Start thread
boost::thread t(&ThreadFunctionSleep);
// Wait for Enter
std::cout << boost::this_thread::get_id() << " Waiting for Enter" << std::endl;
char ch;
cin.get(ch);
// Ask thread to stop
//std::cout << t.get_id() << " joinable " << t.joinable() << std::endl;
try
{
t.interrupt();
}
catch(boost::thread_interrupted&)
{
std::cout << boost::this_thread::get_id() << " Thread is stopped" << std::endl;
}
catch ( boost::thread_resource_error &)
{
std::cout << boost::this_thread::get_id() << " boost thread_resource_error" << std::endl;
}
// Join - wait when thread actually exits
try
{
t.join();
}
catch(boost::thread_interrupted&)
{
std::cout << boost::this_thread::get_id() << " Thread is joined" << std::endl;
}
catch(boost::system::system_error &)
{
std::cout << boost::this_thread::get_id() << " boost system_error" << std::endl;
}
catch(...)
{
std::cout << boost::this_thread::get_id() << " other exception" << std::endl;
}
cout << boost::this_thread::get_id() << " main: thread ended" << endl;
return 0;
}
私が期待する私のプログラムの出力は次のようなものです:
4f4 main thread
1264 worker thread
4f4 Waiting for Enter
1264 thread iteration 1 Press Enter to stop
1264 thread iteration 2 Press Enter to stop
1264 Thread is stopped in ThreadFunction
4f4 main: thread ended
先頭の数字はスレッド ID です。問題は、これがまったく表示されないことです。Enter キーを押した後にコードが実行される方法は 3 つあります。これは、私が見ていないある種のマルチスレッドの問題を示唆しています。
1) t.join() まで例外はキャッチされず、ワーカー スレッドはメイン スレッドの実行を続行します。
11cc main thread
11cc644 worker thread
644 thread iteration 1 Press Enter to stop
Waiting for Enter
644 thread iteration 2 Press Enter to stop
644 Thread is joined
644 main: thread ended
Process returned 0 (0x0) execution time : 2.750 s
Press any key to continue.
2) プログラムのクラッシュ
11cc main thread
11cc644 worker thread
644 thread iteration 1 Press Enter to stop
Waiting for Enter
644 thread iteration 2 Press Enter to stop
644 Thread is joined
644 main: thread ended
Process returned 0 (0x0) execution time : 2.750 s
Press any key to continue.
3) めったに発生しないが、とにかくクラッシュする
11cc main thread
11cc644 worker thread
644 thread iteration 1 Press Enter to stop
Waiting for Enter
644 thread iteration 2 Press Enter to stop
644 Thread is stopped in ThreadFunction
メインスレッドが通常どおり続行されるように、ワーカースレッドでboost::thread_interruptedをキャッチするにはどうすればよいですか?? 同様に、sleep_for() の代わりに timed_wait() を使用する場合、他に何か考慮する必要がありますか??
ブースト 1.53.0 と MinGW 4.4.1 を使用しています。boost::thread と boost::system に runtime-link-static マルチスレッド ライブラリを使用しています。
ありがとう