Я комментировал ответ , что локальное хранилище хорошо, и вспомнил другое информативное обсуждение об исключениях, где я предполагал
Единственная особенность
среда выполнения в броске
блок в том, что объект исключения
ссылается на rethrow.
Если сложить два и два вместе, разве не будет выполнен весь поток внутри блока функции-перехвата его основной функции, наполнить его локальным хранилищем потока?
Кажется, все работает нормально, хотя и медленно. Это роман или хорошо охарактеризован? Есть ли другой способ решения проблемы? Была ли моя первоначальная предпосылка правильной? Какие издержки 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 делает три звонки на pthread_getspecific
в get_thread
. РЕДАКТИРОВАТЬ: и множество неприятных самоанализа в стеке, среде и исполняемом формате, чтобы найти блок catch
, который я пропустил при первом прохождении. Это выглядит сильно зависящим от платформы, так как GCC вызывает около 1030 * из ОС. Накладные расходы порядка 4000 циклов. Я предполагаю, что это также должно пересечь иерархию классов, но это можно держать под контролем.