web-dev-qa-db-fra.com

Comment puis-je obtenir un ID de thread à partir d'un pthread_t arbitraire?

J'ai un pthread_t, et je voudrais changer son affinité CPU. Le problème est que j'utilise la glibc 2.3.2, qui n'a pas pthread_setaffinity_np () . C'est OK, cependant, car pthread_setaffinity_np () est lui-même un wrapper de sched_setaffinity () , qui peut être appelé en passant un ID de thread au lieu d'un ID de processus pour définir l'affinité pour un thread arbitraire.

[~ # ~] mais [~ # ~] ... L'ID de thread avec lequel sched_setaffinity peut fonctionner est un ID de thread de système d'exploitation, le type que vous peut obtenir de l'appel système gettid () . Ceci est différent du type opaque pthread_t , et gettid () ne renverra que l'ID de thread du thread actuel =. J'ai besoin de pouvoir définir l'affinité CPU d'un thread arbitraire.

Malheureusement, je ne peux pas accéder aux parties privées du pthread, ce qui me permettrait de voler l'identifiant du thread en castant un pthread_t en struct pthread *. Tant mieux, je suppose, car compter sur des implémentations privées demande même plus problème.

J'ai également lu la fonction pthread_getunique_np , mais cela renvoie un "identifiant intégral unique" - qui, je ne crois pas, est en aucune façon une forme ou une forme équivalente à un ID de thread OS.

Par conséquent, la question: comment puis-je obtenir un ID de thread à partir d'un pthread_t arbitraire?

38
Skrud

Comme pthreads n'a pas besoin d'être implémenté avec des threads Linux (ou des threads du noyau, d'ailleurs) et que certaines implémentations sont entièrement de niveau utilisateur ou mixtes, l'interface pthreads ne fournit pas pour accéder à ces détails d'implémentation, car ceux-ci ne seraient pas portables (même sur les implémentations de pthreads sous Linux). Les bibliothèques de threads qui les utilisent pourraient fournir ceci comme une extension, mais il ne semble pas y en avoir.

Outre l'accès aux structures de données internes de la bibliothèque de threads (ce que vous ne voulez naturellement pas, bien qu'avec vos hypothèses sur l'affinité du processeur et les ID de threads Linux, votre code ne sera de toute façon pas portable), vous pourrez peut-être jouer un tour au moment de la création , si vous contrôlez le code qui crée les threads:

Donnez à pthread_create() une fonction d'entrée qui appelle gettid() (ce que vous devrez probablement faire en utilisant directement la macro syscall car elle n'est pas toujours exportée par libc), stocke le résultat quelque part, puis appelle la fonction d'entrée d'origine. Si vous avez plusieurs threads avec la même fonction d'entrée, vous pouvez passer un pointeur incrémenté dans un tableau dans l'argument arg à pthread_create, qui sera ensuite transmis à la fonction d'entrée que vous avez créée pour stocker l'ID de thread. Stockez le pthread_t renvoie la valeur de pthread_create dans le même ordre, puis vous pourrez rechercher les ID de threads Linux de tous les threads que vous avez créés en fonction de leur pthread_t valeur.

Que cette astuce en vaille la peine, cela dépend de l'importance de la définition de l'affinité CPU dans votre cas, par rapport à l'absence d'accès aux structures internes de la bibliothèque de threads ou en fonction d'une bibliothèque de threads qui fournit pthread_setaffinity_np.

33
Tom Alsberg

Réellement pthread_self Retour pthread_t et non pas un identifiant de thread entier avec lequel vous pouvez travailler, la fonction d'assistance suivante vous permettra d'obtenir cela de manière portable sur différents systèmes POSIX.

uint64_t gettid() {
    pthread_t ptid = pthread_self();
    uint64_t threadId = 0;
    memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid)));
    return threadId;
}
12
jayadev
pthread_t pthread_self()

ce retour retourne pthread_t, qui est l'identifiant du thread, vous pouvez le convertir en type "unsigned int",

1
Eric Wang

Dans glibc 2.24 le pthread_t retourné est juste le pointeur vers un opaque struct pthread. Vous pouvez rechercher la définition dans nptl/descr.h.

1
Giuseppe Corbelli

Je suggérerais une solution de contournement simple avec un tableau int partagé où vous pourriez écrire l'ID de thread à partir des threads pour y accéder plus tard.

J'espère que cela pourra aider.

1
Kamil Zadora