在 throw 块中,执行环境唯一特殊的事情是 rethrow 引用了异常对象。
综合考虑,将整个线程放在其主函数的函数 catch 块内部是否赋予它线程本地存储?
看起来可以正常工作,尽管速度较慢。这是新颖的还是已经被描述清楚了?还有其他解决问题的方法吗?我的最初假设是否正确? 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()
初始化基类,但总体来说,这不像是一个无所事事的失眠星期天早上...
编辑:看起来GCC在get_thread
中调用了三次pthread_getspecific
。编辑:还有一些对堆栈、环境和可执行文件格式的恶意内省,以找到我在第一次检查中错过的catch
块。这看起来高度依赖平台,因为GCC正在从操作系统调用一些libunwind
。开销约为4000个周期。我想它也必须遍历类层次结构,但可以控制。