Comment obtenir un identifiant de thread entier en c ++ 11

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 classe std::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