Boost.thread を内部で使用する共有ライブラリを構築しています。その結果、Boost.thread がそれに依存するため、Boost.system も使用されます。私の共有ライブラリは C インターフェイスをエクスポートするため、内部例外処理やスレッドの使用などをすべてエンド ユーザーから隠したいと考えています。いわばブラックボックスのはずです。ただし、クライアントアプリケーションとリンクすると、プログラムは正常に実行されますが、ライブラリ関数を呼び出して処理を停止するとすぐに、次のようになります。
「boost::thread_interrupted」のインスタンスをスローした後に呼び出される終了
私はこの例外をライブラリの内部でキャッチするので、なぜ実際にキャッチされないのかわかりません。エンド ユーザーのプログラムは、Boost 例外を認識したり、処理したりすることを意図したものではありません。共有ライブラリを構築するときは、Boost.thread と Boost.system の両方に静的リンクを使用するので、外の世界からそれらが見えないようにしています。私はUbuntu 12でGCC 4.7を使用しています。Windowsでは、そのような問題はありません(MSVCでもMinGwでも)。
(編集)
コメントのリクエストに従って、問題を再現する最小限の例を示すために質問を編集しています。
最初に、testlib.cpp と testlib.h のコードを示します。
testlib.cpp:
#include <boost/thread/thread.hpp> void thread_func() { ながら(1) { ブースト::this_thread::interruption_point(); } } ボイド do_processing() { // 上記の関数を実行するスレッドを開始します。 ブースト::スレッドワーカー(thread_func); // この例では、スレッドが適切に開始されたと想定しています。 // スレッドを中断しましょう。 worker.interrupt(); // そして、終了するのを待ちましょう。 worker.join(); }
そして今、testlib.h:
#ifndef TESTLIB_H #TESTLIB_H を定義 void do_processing(); #endif
次のコマンドを使用して、これを共有ライブラリにビルドします。
g++ -static-libgcc -static -s -DNDEBUG -I /usr/boost_1_54_0 -L /usr/boost_1_54_0/stage/lib -Wall -shared -fPIC -o libtestlib.so testlib.cpp -lboost_thread -lboost_system -lpthread -O3
次に、次のような単純なクライアント プログラムのコードを作成します。
#include "testlib.h" #include <cstdio> int main() { do_processing(); printf("実行は正常に完了しました。\n"); 0 を返します。 }
次のようにクライアントを構築します。
g++ -DNDEBUG -I /usr/boost_1_54_0 -L ./ -Wall -o クライアント client.cpp -ltestlib -O3
クライアントを実行すると、次のようになります。
'boost::thread_interrupted' のインスタンスをスローした後に呼び出された終了
中止 (コア ダンプ)
私はスレッド割り込み例外を明示的にキャッチしていませんが、Boost ドキュメントによると、Boost.thread はそれを行い、指定されたスレッドのみを終了します。thread_func 関数内から例外を明示的にキャッチしようとしましたが、違いはありませんでした。
(編集終了)
(編集2)
-fexceptions をオンにしても、問題は解決しないことに注意してください。また、例外をキャッチしてスローするコードと同じ翻訳単位で定義されている例外をスローしてキャッチしようとしましたが、改善されませんでした。要するに、すべての例外は、共有ライブラリでキャッチされていないように見えます。クライアント ファイルと testlib ファイルを 1 つのプログラムの一部としてコンパイルすると、つまり testlib を共有ライブラリにしないと、すべてが期待どおりに機能します。
(編集2の終わり)
任意のヒント?