私は、スレッドローカルストレージが優れているという回答にコメントしていましたが、私が想定していた例外に関する別の有益な議論を思い出しました
throw ブロック内の実行環境に関する唯一の特別な点は、例外オブジェクトが rethrow によって参照されることです。
2 つと 2 つをまとめると、メイン関数の関数キャッチ ブロック内でスレッド全体を実行すると、スレッド ローカル ストレージが吹き込まれませんか?
ゆっくりではありますが、うまく機能しているようです。これは小説ですか、それともよく特徴付けられていますか? 問題を解決する別の方法はありますか?私の最初の前提は正しかったですか?プラットフォームでどのようなオーバーヘッドがget_thread
発生しますか? 最適化の可能性は?
#include <iostream>
#include <pthread.h>
using namespace std;
struct thlocal {
string name;
thlocal( string const &n ) : name(n) {}
};
struct thread_exception_base {
thlocal &th;
thread_exception_base( thlocal &in_th ) : th( in_th ) {}
thread_exception_base( thread_exception_base const &in ) : th( in.th ) {}
};
thlocal &get_thread() throw() {
try {
throw;
} catch( thread_exception_base &local ) {
return local.th;
}
}
void print_thread() {
cerr << get_thread().name << endl;
}
void *kid( void *local_v ) try {
thlocal &local = * static_cast< thlocal * >( local_v );
throw thread_exception_base( local );
} catch( thread_exception_base & ) {
print_thread();
return NULL;
}
int main() {
thlocal local( "main" );
try {
throw thread_exception_base( local );
} catch( thread_exception_base & ) {
print_thread();
pthread_t th;
thlocal kid_local( "kid" );
pthread_create( &th, NULL, &kid, &kid_local );
pthread_join( th, NULL );
print_thread();
}
return 0;
}
これには、から派生した新しい例外クラスを定義しthread_exception_base
、ベースを で初期化する必要がありget_thread()
ますが、全体として、これは非生産的な不眠症に悩まされている日曜日の朝のようには感じられません…</p>
編集: GCC がinを3 回呼び出しているようです。編集:最初のウォークスルーで見逃したブロックを見つけるために、スタック、環境、実行可能形式への多くの厄介な内省。GCC がOS から呼び出しているため、これはプラットフォームに大きく依存しているように見えます。約 4000 サイクルのオーバーヘッド。クラス階層もトラバースする必要があると思いますが、それは制御下に置くことができます。pthread_getspecific
get_thread
catch
libunwind