D'accord, il semble que ceci est ma réponse finale. Nous avons 2 problèmes réels :
- Comment obtenir des identifiants de thread uniques plus courts pour le journal.
- Quoi qu'il en soit, nous devons imprimer l'identifiant pthread_t réel du thread (juste pour lier aux valeurs POSIX au moins).
1. Imprimer l'identifiant POSIX (pthread_t)
Vous pouvez simplement traiter pthread_t comme un tableau d'octets avec des chiffres hexadécimaux imprimés pour chaque octet. Vous n'êtes donc pas limité par un type de taille fixe. Le seul problème est l'ordre des octets. Vous apprécierez probablement si l'ordre de vos octets imprimés est le même que pour un simple "int" imprimé. Voici un exemple pour little-endian et seul l'ordre devrait être inversé (sous define ?) pour big-endian :
#include
#include
void print_thread_id(pthread_t id)
{
size_t i;
for (i = sizeof(i); i; --i)
printf("%02x", *(((unsigned char*) &id) + i - 1));
}
int main()
{
pthread_t id = pthread_self();
printf("%08x\n", id);
print_thread_id(id);
return 0;
}
2. Obtenir un identifiant de thread imprimable plus court
Dans tous les cas proposés, vous devriez traduire l'identifiant de thread réel (POSIX) en index d'une table. Mais il existe 2 approches significativement différentes :
2.1. Suivre les threads.
Vous pouvez suivre les identifiants de threads de tous les threads existants dans une table (leurs appels pthread_create() devraient être enveloppés) et avoir une fonction "surchargée" d'identifiant qui ne vous donne que l'index de la table, pas l'identifiant de thread réel. Ce schéma est également très utile pour tout débogage interne lié aux threads et le suivi des ressources. L'avantage évident est l'effet secondaire de la trace / de l'installation du débogage au niveau du thread avec extension future possible. L'inconvénient est l'exigence de suivre toute création / destruction de thread.
Voici un exemple partiel de pseudocode :
pthread_create_wrapper(...)
{
id = pthread_create(...)
add_thread(id);
}
pthread_destruction_wrapper()
{
/* Le problème principal est qu'il devrait être appelé.
Les appels pthread_cleanup_*() sont une solution possible. */
remove_thread(pthread_self());
}
unsigned thread_id(pthread_t known_pthread_id)
{
return seatch_thread_index(known_pthread_id);
}
/* code utilisateur */
printf("04x", thread_id(pthread_self()));
2.2. Enregistrer simplement un nouvel identifiant de thread.
Pendant l'appel au journal, appelez pthread_self() et recherchez dans la table interne si le thread est connu. Si un thread avec un tel identifiant a été créé, son index est utilisé (ou réutilisé à partir d'un thread précédent, en fait cela n'a pas d'importance car il n'y a pas 2 mêmes ID pour le même moment). Si l'identifiant du thread n'est pas encore connu, une nouvelle entrée est créée donc un nouvel index est généré / utilisé.
L'avantage est la simplicité. L'inconvénient est l'absence de suivi de la création / destruction de thread. Donc pour suivre cela, une mécanique externe est requise.