ero commenting on an answer che lo stoccaggio filo-locale è bello e ha ricordato un altro informative discussion sulle eccezioni in cui avrei dovutoLe eccezioni C++ sono sufficienti per implementare l'archiviazione locale dei thread?
L'unica cosa speciale per l'ambiente di esecuzione all'interno del blocco tiro è che l'oggetto eccezione è riferimento da rethrow.
Mettendo due e due insieme, non si eseguiva un'intera discussione all'interno di un blocco di funzioni della sua funzione principale che lo riempiva di memoria locale del thread?
Sembra funzionare bene, anche se lentamente. Questo romanzo è ben caratterizzato? C'è un altro modo per risolvere il problema? La mia premessa iniziale era corretta? Che tipo di overhead compie get_thread
sulla tua piattaforma? Qual è il potenziale per l'ottimizzazione?
#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;
}
Questo richiede la definizione di nuove classi di eccezioni derivate da thread_exception_base
, inizializzare la base con get_thread()
, ma tutto questo non si sente come un improduttivo insonnia cavalcato Domenica mattina ...
EDIT: Sembra GCC effettua tre chiamate a pthread_getspecific
in get_thread
. EDIT: e molta introspezione in stack, ambiente e formato eseguibile per trovare il blocco catch
che ho perso durante la prima procedura. Questo sembra molto dipendente dalla piattaforma, poiché GCC chiama alcuni libunwind
dal sistema operativo. Sovraccarico dell'ordine di 4000 cicli. Suppongo che debba anche attraversare la gerarchia delle classi, ma ciò può essere tenuto sotto controllo.
È una funzione try/catch block consentita per main? –
Certamente, lo standard specifica che il blocco catch principale non gestisce i lanci dai costruttori globali/statici. Non che sia essenziale per questo meccanismo. – Potatoswatter
Cosa succede se viene lanciata una seconda eccezione? –