c ++ 11 a la possibilité d’obtenir l’identifiant de thread actuel, mais il ne peut pas être converti en type entier:
cout<<std::this_thread::get_id()<<endl;
sortie: 139918771783456
cout<<(uint64_t)std::this_thread::get_id()<<endl;
erreur: dissortingbution invalide de type ‘std :: thread :: id’ pour taper ‘uint64_t’ idem pour les autres types: transtypage invalide de type ‘std :: thread :: id’ pour taper ‘uint32_t’
Je ne veux vraiment pas faire un lancer de pointeur pour obtenir l’identifiant du thread entier. Existe-t-il un moyen raisonnable (standard parce que je veux qu’il soit portable) pour le faire?
La solution portable consiste à transmettre vos propres identifiants générés dans le thread.
int id = 0; for(auto& work_item : all_work) { std::async(std::launch::async, [id,&work_item]{ work_item(id); }); ++id; }
Le type std::thread::id
doit être utilisé uniquement pour les comparaisons, pas pour l’arithmétique (c’est-à-dire comme il est dit sur la boîte: un identifiant ). Même sa représentation textuelle produite par l’ operator<<
n'est pas spécifiée , vous ne pouvez donc pas compter sur la représentation d'un nombre.
Vous pouvez également utiliser une carte des valeurs std::thread::id
dans votre propre identifiant, et partager cette map (avec une synchronisation correcte) entre les threads, au lieu de passer directement l'identifiant.
Vous avez juste besoin de faire
std::hash{}(std::this_thread::get_id())
pour obtenir une size_t
.
De cppreference :
La spécialisation template de
std::hash
pour la classestd::thread::id
permet aux utilisateurs d’obtenir des hachages des identifiants des threads.
Un autre identifiant (idée? ^^) serait d’utiliser des chaînes de caractères:
std::ssortingngstream ss; ss << std::this_thread::get_id(); uint64_t id = std::stoull(ss.str());
Et utilisez try catch si vous ne voulez pas d’exception en cas de problème ...
Une idée serait d’utiliser le stockage local de threads pour stocker une variable – peu importe le type, tant qu’elle respecte les règles du stockage local des threads – puis d’utiliser l’adresse de cette variable comme “identifiant de thread”. Evidemment, toute arithémétique ne sera pas significative, mais ce sera un type intégral.
Pour la postérité: pthread_self()
renvoie un pid_t
et est posix. Ceci est portable pour une définition de portable.
gettid()
, certainement pas portable, mais il renvoie une valeur amicale de GDB.
Je ne sais vraiment pas à quelle vitesse cela se passe, mais c’est la solution que j’ai réussi à inviter:
const size_t N_MUTEXES=128;//UINT_MAX,not 128 for answer to my original question hash h; cout<
Encore une fois, je commence à penser que trouver un pointeur sur la structure et la lancer dans unsigned int ou uint64_t est la réponse ... EDIT:
uint64_t get_thread_id() { static_assert(sizeof(std::thread::id)==sizeof(uint64_t),"this function only works if size of thead::id is equal to the size of uint_64"); auto id=std::this_thread::get_id(); uint64_t* ptr=(uint64_t*) &id; return (*ptr); } int main() { cout<
static_assert pour éviter les problèmes d'enfer 🙂 La réécriture est facile comparée à la recherche de ce type de bogue. 🙂
thread::native_handle()
renvoie thread::native_handle_type
, qui est un typedef à long unsigned int
.
Si le thread est construit par défaut, native_handle () renvoie 0. Si un thread de système d’exploitation lui est associé, la valeur renvoyée est différente de zéro (c’est pthread_t sur POSIX).
cela dépend de ce que vous voulez utiliser le thread_id pour; vous pouvez utiliser:
std::ssortingngstream ss; ss << std::this_thread::get_id(); uint64_t id = std::stoull(ss.str());
Cela générera un identifiant unique avec votre processus; mais il y a une limitation: si vous lancez plusieurs instances du même processus et que chacune d'entre elles écrit ses identifiants de threads dans un fichier commun, l'unicité de thread_id n'est pas garantie; En fait, il est fort probable que vous aurez des chevauchements. Dans ce cas, vous pouvez faire quelque chose comme:
#include timespec ts; clock_gettime(CLOCK_REALTIME, &ts); uint64_t id = (ts.tv_sec % 1000000000) * 1000000000 + ts.tv_nsec;
maintenant, vous êtes garanti des identifiants de threads uniques dans tout le système.
De cette façon, devrait fonctionner:
std::ssortingngstream ss; ss << std::this_thread::get_id(); int id = std::stoi(ss.str());
N'oubliez pas d'inclure la bibliothèque sstream