2017-10-20 24 views
0

Je connais le difference entre pthread_self() et syscall(SYS_gettid). pthread_create() produit un ID de thread POSIX qui est représenté par une structure pthread_t qui est généralement définie comme unsigned long int. Nous pouvons utiliser pthread_self pour obtenir le ID of the thread généré par pthread_create.Est-ce que l'ID de thread Posix a une relation bi-univoque avec l'ID de thread Linux?

Avec strace, je sais que dans pthread_create() libpthread.so.0 est mis en œuvre en appelant clone appel système, qui est aussi l'appel système utilisé pour fork(). Après avoir créé un thread POSIX en appelant pthread_create(), un nouveau thread POSXI (identifié par l'ID de thread retourné par pthread_self()) et un nouveau thread Linux (identifié par l'ID de thread retourné par syscall(SYS_gettid)) sont générés. Est-ce que cela signifie que l'ID de thread POSIX a une relation un-à-un avec l'ID de thread Linux? Ils représentent respectivement le fil avec pthread_t et pid_t? En fait, parfois, j'ai trouvé qu'un ID thread linux correspond à plusieurs ID threads POSIX dans le même processus, ce qui signifie qu'après avoir généré une paire d'ID threads POSIX et un ID thread linux en appelant pthread_create(), l'ID de thread POSIX change L'ID de thread Linux reste le même. Est-il possible de modifier l'ID de thread POSIX tout en conservant l'ID de thread linux inchangé? S'il y a, quelle est la fonction pthread?

Merci.

Voici le journal en intercepter fork et pthread_create appel. ltid signifie ID de thread linux, tid signifie ID de thread POSIX, pid signifie ID de processus.

1 message: fork pid:12832 ltid:12832 tid:140300035462976  child pid:12848 ltid:12848 tid:140300035462976 

2 message: fork pid:12848 ltid:12848 tid:140549640255296  child pid:12849 ltid:12849 tid:140549640255296 

3 message: fork pid:12848 ltid:12848 tid:140549640255296  child pid:12850 ltid:12850 tid:140549640255296 

4 message: fork pid:12848 ltid:12848 tid:140549640255296  child pid:12851 ltid:12851 tid:140549640255296 

5 message: pthread_create pid:12848 ltid:12848 tid:139968995022656  child ltid:12865 tid:139968995018496 

6 message: pthread_create pid:12848 ltid:12865 tid:139968995018496  child ltid:12865 tid:139968933345024 

7 message: fork pid:12832 ltid:12832 tid:140300035462976  child pid:12885 ltid:12885 tid:140300035462976 

8 message: fork pid:12885 ltid:12885 tid:139870512949056  child pid:12886 ltid:12886 tid:139870512949056 

Mon explication:

  1. (pid = 12832, ltid = 12832, tid = 140 ... 976) appelle la production fork (pid = 12848, ltid = 12848, tid = 140 .. .976)
  2. (pid = 12848, ltid = 12848, tid = 140 ... 296) appelle fork production (pid = 12849, ltid = 12849, tid = 140 ... 296)
  3. (pid = 12848 , ltid = 12848, tid = 139 ... 656) appelle pthread_create produisant (ltid = 12865, tid = 139 ... 496)

L'appelant de 2 est le résultat de 1 en fonction de l'ID de thread Linux (12848), mais ils ont des ID de threads POSIX différents. La même chose vaut pour 1 et 5.

Voici le fragment de code d'interception.

void *intermedia(void * arg){ 

    struct thread_param *temp; 

    void *(*start_routine) (void *); 
    temp=(struct thread_param *)arg; 

    char test[1024]=""; 
    sprintf(test,"child ltid:%ld\ttid:%lu\n",syscall(SYS_gettid),pthread_self()); 
    log_message(test) 

    return temp->start_routine(temp->args);  
} 


int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg){ 
    static void *handle = NULL; 
    static P_CREATE old_create=NULL; 
    if(!handle) 
    { 
     handle = dlopen("libpthread.so.0", RTLD_LAZY); 
     old_create = (P_CREATE)dlsym(handle, "pthread_create"); 
    } 
    pthread_t tmp=pthread_self(); 
    char test[1024]=""; 
    sprintf(test,"pthread_create pid:%d\tptid:%ld\ttid:%lu\n",getpid(),syscall(SYS_gettid),tmp); 
    log_message(test); 

    struct thread_param *temp=malloc(sizeof(struct thread_param)); 
    temp->args=arg; 
    temp->start_routine=start_routine; 

    int result=old_create(thread,attr,intermedia,(void *)temp); 

    return result; 
} 

pid_t fork(void){ 
    static void *handle = NULL; 
    static FORK old_fork=NULL; 
    if(!handle) 
    { 
     handle = dlopen("libc.so.6", RTLD_LAZY); 
     old_fork = (FORK)dlsym(handle, "fork"); 
    } 

    char test[1024]=""; 
    sprintf(test,"fork pid:%d\tltid:%ld\ttid:%lu\t",getpid(),syscall(SYS_gettid),pthread_self()); 

    pid_t ppid=getpid(); 
    pthread_t ptid=pthread_self(); 
    pid_t result=old_fork(); 
    if(result==0){ 
     sprintf(test,"%s\tchild pid:%d\tltid:%ld\ttid:%lu\n",test,getpid(),syscall(SYS_gettid),pthread_self()); 
     log_message(test); 
    } 
    return result; 
} 
+0

La balise "linuxthreads" semble incorrecte dans le contexte, car "linuxthreads" est différent des threads POSIX. – alk

+0

@alk Cela signifie-t-il le noyau Linux? Si ce n'est pas correct, je peux supprimer cette balise. – Chalex

+0

Sur l'histoire de threading sur Linux: http://www.drdobbs.com/open-source/nptl-the-new-implementation-of-threads-f/184406204 (la lecture pourrait apporter de la clarté sur les différentes formulations) – alk

Répondre

1

Est-ce que Posix ID de fil ont un one-to-one relation avec fil linux ID

Oui. Mais considérons ceci comme un détail de mise en œuvre.

D'autres systèmes d'exploitation peuvent le faire différemment.


qui est généralement définie comme

pthread_t est opaque. De même, ne faites aucune hypothèse sur la façon dont il est mis en œuvre.


Je trouve qu'un fil linux cartes d'identité à plusieurs identifiants de thread POSIX

Vraiment? Je doute de cela. Du moins pas si tous les ID de threads POSIX en question étaient valides, c'est-à-dire que le thread associé n'avait pas encore été joint ou, s'il était détaché, le thread n'était pas encore terminé.

+0

Ils sont tous valables dans mon cas de test. Parce que j'ai intercepté tout appel 'pthread_create()' pour enregistrer la relation parent-enfant entre les threads. – Chalex

+0

@Chalex: Osez montrer le code du cas de test? – alk

+0

Ils sont tous valables dans mon cas de test. Parce que j'ai intercepté tout appel 'pthread_create()' pour enregistrer la relation parent-enfant entre les threads. J'ai trouvé les threads avec le même ID de thread Linux mais différents ID de thread POSIX tous appelés 'pthread_create()', ce qui signifie qu'ils ont été exécutés. – Chalex