IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Qu'est ce que pthread_t ?


Sujet :

Linux

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Points : 8
    Points
    8
    Par défaut Qu'est ce que pthread_t ?
    Bonjour à tous ! (LINUX CODE - Fedora Core)

    J'ai besoin de récupérer l'ID d'un thread, j'utilise donc pthread_self(), mais cette fonction me retourne un pthread_t ... J'ai beau le caster en ce que je veux, ce soit disant ID de thread est complétement pourri. L'ID qui m'interesse est celui qui est affiché lorsqu'on fait un ps systéme ...

    J'ai reussi à recup cet ID en faisant une grosse bidouille, en gros j'ai un

    typedef unsigned long int pthread_t;

    J'ai dédui que ca pouvait être un pointeur et bingo !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     unsigned short lThreadID;
    memcpy(&lThreadID, (void*)(pthread_self()+72), sizeof(unsigned short));
    Et la j'ai bien mon thread ID correct, je retrouve aussi le thread ID du pére un peu plus loin dans la mémoire.
    J'en ai donc deduis que pthread_t qui est défini comme un unsigned long est en réalité un pointeur sur une struct, mais je tape direct dans la mémoire c crade, j'aimerai pouvoir caster mon unsigned long comme un pointeur sur cette struct mais je ne sais pas du tout de quelle struct il s'agit et je ne trouve AUCUNE info la dessus sur le net

    A l'aide !

  2. #2
    Futur Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Points : 8
    Points
    8
    Par défaut
    Alors pas d'experts Linux présents ?

    J'avoue que c'est trés trés flou comme truc j'ai l'impression. D'habitude quand je développe je n'ai jamais recours aux forums pour m'en sortir, mais la franchement je suis tombé sur un truc qui me dépasse.

    HeLP !

  3. #3
    zul
    zul est déconnecté
    Membre éclairé Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Points : 699
    Points
    699
    Par défaut
    pthread_t est une structure opaque définie par Posix. On sait qu'il existe un type pthread_t qu'on peut manipuler avec un certains nombre de fonctions définis dans la norme Posix.

    Tout le reste n'est que détail d'implémentation, et ton truc un horrible hack qui est même pas sur qu'il va marcher sur un autre linux.

    Pourquoi as tu besoin de savoir ca ? que veux tu faire ?
    A mon avis, la question est plus lié à l'environnement unix qu'au C standard.

  4. #4
    Futur Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Points : 8
    Points
    8
    Par défaut
    Oui c'est crade et je sais que ca sera pas cross platform mais de toute facon cette lib hummmm ... bon je dirai rien ...

    Je veux juste recup l'ID du thread ...

    pthread_self() est censé faire ca, mais non il me renvoie ce pthread_t qui n'est en aucun cas l'ID du thread dans la forme qui m'intérésse (je suis obligé de taper dans la mémoire pointée par le pointeur renvoyé pour trouver mon bonheur). Si c'est si bien les thread posix sous linux y doit bien y avoir une super jolie fonction qui me retourne l'ID du thread tel que je le vois quand je fais un "ps" dans ma console Linux.

  5. #5
    zul
    zul est déconnecté
    Membre éclairé Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Points : 699
    Points
    699
    Par défaut
    ps il tape dans /proc cad dans le kernel. L'approche est donc franchement différente. Je ne vois pas ce que tu appelle id du thread ( dans le output de ps ) , peux tu nous renseigner la dessus.

    Si tu veux avoir la définition exacet d'un pthread , telecharge les sources de la glibc, il est défini dans glibc/nptl/descr.h. Le cauchemar ne fait que commencer.

  6. #6
    Futur Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Points : 8
    Points
    8
    Par défaut
    Bon en gros j'ai plusieurs threads qui tournent, et j'ai un thread de surveillance, qui posséde un tableau de pointeurs sur l'ensemble des mutex de mes threads et vérifie periodiquement si les mutex sont bloqués par des threads.

    Il récupére l'ID du thread lockant le mutex par le trick suivant :

    monMutex.__data.__owner

    monMutex étant de type mutex_t.

    Ici l'ID du thread correspond bien à celui affiché par le kernel dans ps !

    C'est celui que j'aimerai recuperer en faisant un pthread_self().

    Mais ce n'est pas le cas, je vais regarder la structure, merci.

  7. #7
    zul
    zul est déconnecté
    Membre éclairé Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Points : 699
    Points
    699
    Par défaut
    Le but est de faire le code le moins portable possible en utilisant le nombre de truc implémentation spécifique le plus grand ?

    Pourquoi ne crée tu pas simplement une structure comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct mutex_listen{
    pthread_mutex_t mutex;
    pthread_t thread;
    };
    et un simple wrapper autour de mutex_lock / mutex_unlock ?

    C'est une idée comme ca, elle n'est peut-etre pas correcte, mais elle semble plus plaisant et moins envahissante

  8. #8
    Futur Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Points : 8
    Points
    8
    Par défaut
    Pour notre application chaque thread posséde un fichier de log qui contient l'ID du thread au debut de chaque ligne (ID PROCESS / ID THREAD / MESSAGE).

    Actuellement avec pthread_t, soit disant un ID de thread (qui est en fait un pointeur, donc ok on peut voir ca comme un ID si on veut), je recup un truc imbitable qui ne correspond à rien, je comprend fort bien que ce handle puisse servir à faire des comparaisons internes ou des traitements internes sur son ID, mais notre programme doit afficher l'ID de maniére externe et lisible et comparable avec le "ps" pour l'utilisateur client de notre application.

    Ce n'est pas plus compliqué que ca, je ne veux donc pas d'un pthread_t vulgaire sauf pour travailler en interne et non exposé à l'utilisateur eventuellement, mais cela sort du contexte de mon probléme actuel.

  9. #9
    Futur Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Points : 8
    Points
    8
    Par défaut
    Le pire c'est que cet ID est contenu dans la memoire pointé par le pthread_t !

    Donc ca correspond à une structure ou qqch je sais pas.

    Tout ce que je veux c'est recupérer ca de maniére plus propre que de taper à la crados dans la mémoire ... L'info dont j'ai besoin est LA, elle est PRESENTE ! Mais OU EST L'ACCESSEUR BORDEL ! C'est quoi cette lib serieux ? !

  10. #10
    zul
    zul est déconnecté
    Membre éclairé Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Points : 699
    Points
    699
    Par défaut
    pthread_t est une interface de programmation : un type opaque pour l'utilisateur. Posix ne définit pas le contenu de cette structure. Pour éviter que l'on fasse n'importe quoi, la glibc cache le type à l'utilisateur comme ca il n'est pas tenté d'ecrire des choses pas portable.

    Il n'y a pas d'accesseur parce que l'utilisateur n'est pas censé manipulé ce type autrement que par les fonctions définis par posix. C'est de la salade interne. Imagine une interface java et des données privées par exemple : tu n'a aucun moyen d'acceder aux données privées.

    Pour en revenir à ton problème, le premier problème vient du fait que tu utilise un détail de l'implémentation pour récupérer des informations sur les mutex, evidemment tu as ensuite besoin d'informations privées dans le thread et ca devient le drame. L'application devrait être pensé en utilisant l'interface que l'on donne, pas en esperant qu'un hack pourra te sauver la mise.

    Pour répondre précisement à ton problème, et quiite à écrire du code sale, tu dois pouvoir faire ca
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <nptl/descr.h>
     
    pthread_t false_id ;
    pid_t true_id;
    struct pthread * p;
     
    false_id = pthread_self();
    p = (struct pthread * ) false_id;
    true_id = p->tid;
    ce qui reste d'après moi une mauvaise solution, couteuse à maintenir, difficile à déployer, non portable, et tout ce qui va avec ...

  11. #11
    Futur Membre du Club
    Inscrit en
    Septembre 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 20
    Points : 8
    Points
    8
    Par défaut
    Merci pour toutes ces infos Zul ...

    Et merci à Linux pour être aussi prise de tête

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3
    Points : 4
    Points
    4
    Par défaut Récapitulatif - Synthèse
    Merci pour ces réponses ça m'a permis de faire un tour d'horizon des différentes solutions

    J'écris ici le résultat de ma recherche au cas où cela aiderait un autre développeur ;-)

    Donc, sous Unix le thread_id correspond au code retourné par la fonction pthread_self().

    Mais sous Linux, c'est différent.

    D'abord les deux solutions enoncées sur ce forum :
    1. memcpy( &thread_id, (void*)(pthread_self()+72), sizeof(pid_t) );
    2. thread_id = ((struct pthread*) pthread_self())->tid

    La première est moche et la seconde nécessite d'inclure <nptl/descr.h>.

    N'ayant pas le fichier descr.h sur mon poste et voulant que mon code soit compilable sur n'importequel poste Linux, j'ai cherché une autre solution, et j'ai trouvé la fonction gettid(void) specific à Linux [man gettid].
    => thread_id = gettid();

    Cette fonction nécessite d'inclure le fichier <linux/unistd.h>.
    (c'est le fichier qui définit aussi la fonction getpid(void))

    Manque de pot, mon header "unistd.h" ne contient pas cette fonction !

    Et j'ai finalement trouvé une troisième solution = effectuer moi même l'appel système de gettid au kernel :
    => __asm__("int $0x80" : "=a" (thread_id) : "0" (224));

    L'exemple vient du fichier ./wine-0.9.20/libs/port/gettid.c
    extrait à partir de l'archive
    http://www.ibiblio.org/pub/linux/sys...0.9.20.tar.bz2

    Je pense que le code 224 de l'appel système ne changera pas avant le passage au futur kernel 2.8.
    Par contre, l'offset 72 du memset peut changer lors de la prochaine version de la glibc...

    (;-)liver

  13. #13
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Ok... Sauf si je me trompe, il y a un gros problème dans ce que tu assumes : ps ne permet aucunement de faire des distinctions entre les threads, ps traite avec des processus et leurs id (pid), les pthread_t et autres sont des détails internes aux processus qui ne concernent absolument pas ps. Quel est le véritable but final de ton application ?

    --
    Jedaï

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3
    Points : 4
    Points
    4
    Par défaut L'utilité de connaître le ThreadID dans son code
    Salut Jedaï,

    ps permet aussi d'afficher les ThreadID, essaye ça:
    Voici un résumé de mon application, et de l'utilité d'obtenir le ThreadID :

    Au lancement, mon application initialise tout un tas de pthreads. Puis, cette application reste active pendant des jours et des jours...

    Il est utile de jeter un oeuil régulièrement (ou en cas de pépin) sur le serveur.
    La commande ps (du style "ps axmo fname,thcount,state,tid,eip,%mem,%cpu,cputime,policy,nice,etime") permet assez facilement d'identifier le thread qui consomme exagérément du CPU et/ou de la mémoire. Mais les pthreads sont identifiés par un ID (et non pas par un nom comme les kthreads).

    Il est alors nécessaire de faire le lien entre le code exécuté par les pthreads et leur identifiant (ID).

    (;-)liver

Discussions similaires

  1. qu'est ce que l'instruction "round"?
    Par isa_21 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 10/03/2003, 10h37
  2. Qu'est ce que c'est : Le GateA20 ?
    Par le mage tophinus dans le forum x86 16-bits
    Réponses: 5
    Dernier message: 24/02/2003, 15h09
  3. Qu'est ce que le cache ?
    Par irrou dans le forum Assembleur
    Réponses: 4
    Dernier message: 24/11/2002, 23h28
  4. Qu'est-ce que c'est que Nessus, ça fait quoi exactement ?
    Par PeterT dans le forum Développement
    Réponses: 3
    Dernier message: 24/07/2002, 11h23
  5. Réponses: 3
    Dernier message: 19/07/2002, 15h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo