Я был комментируя ответ, что поточно-локальное хранилище приятно и напомнило о другом информативном обсуждении о исключения, в которых я предположил
Единственная особенность в среда выполнения внутри броска block является то, что объект исключения на которые ссылается ретрон.
Объединяя два и два вместе, не выполнил бы весь поток внутри блока функций-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()
, но в целом это не похоже на непроизводительное утро, случившееся в бессоннице...
EDIT: Похоже, что GCC выполняет три вызова pthread_getspecific
в get_thread
. EDIT: и много неприятной интроспекции в стек, среду и исполняемый формат, чтобы найти блок catch
, который я пропустил в первом прохождении. Это выглядит очень зависимым от платформы, поскольку GCC вызывает некоторые libunwind
из ОС. Накладные расходы порядка 4000 циклов. Я полагаю, что он также должен пройти иерархию классов, но это может быть под контролем.