Имеет ли ID потока Posix взаимно-однозначное отношение с ID потока Linux?

Я знаю разницу между pthread_self() а также syscall(SYS_gettid), pthread_create() создает идентификатор потока POSIX, который представлен структурой pthread_t, которая обычно определяется как unsigned long int, Мы можем использовать pthread_self чтобы получить идентификатор потока, сгенерированного pthread_create,

С strace, Я знаю это pthread_create() в libpthread.so.0 реализуется путем вызова clone системный вызов, который также является системным вызовом, используемым для fork(), После создания потока POSIX, вызвав pthread_create(), новый поток POSXI (определяется идентификатором потока, возвращенным pthread_self()) и новый поток Linux (определяется идентификатором потока, возвращенным syscall(SYS_gettid)) производятся. Означает ли это, что идентификатор потока POSIX имеет непосредственное отношение с идентификатором потока linux? Они просто соответственно представляют поток с pthread_t а также pid_t?

На самом деле, иногда я обнаруживал, что один идентификатор потока linux сопоставляется с несколькими идентификаторами потока POSIX в одном и том же процессе, что означает, что после создания пары идентификаторов потока POSIX и идентификатора потока linux путем вызова pthread_create(), идентификатор потока POSIX изменяется, в то время как идентификатор потока Linux остается неизменным. Есть ли способ изменить идентификатор потока POSIX, оставив идентификатор потока Linux без изменений? Если есть, который pthread функция это?

Спасибо.

Вот журнал перехвата fork а также pthread_create вызов. ltid означает идентификатор потока Linux, tid означает идентификатор потока POSIX, pid означает идентификатор процесса.

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

Мое объяснение:

  1. (pid = 12832, ltid = 12832, tid = 140... 976) звонки fork производство (pid = 12848, ltid = 12848, tid = 140... 976)
  2. (pid = 12848, ltid = 12848, tid = 140... 296) звонков fork производство (pid = 12849, ltid = 12849, tid = 140... 296)
  3. (pid = 12848, ltid = 12848, tid = 139... 656) звонки pthread_create производство (ltid=12865, tid=139...496)

Вызывающая сторона 2 является результатом 1 в соответствии с идентификатором потока Linux (12848), но они имеют разные идентификаторы потока POSIX. То же самое касается 1 а также 5,

Вот фрагмент кода перехвата.

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;
}

1 ответ

Решение

Имеет ли идентификатор потока Posix взаимно-однозначное отношение с идентификатором потока linux

Да.

Но рассмотрим это как деталь реализации. Другие ОС могут сделать это по-другому.


который обычно определяется как

pthread_t непрозрачный Также не стоит делать никаких предположений о том, как это реализовано.


Я обнаружил, что один идентификатор потока Linux соответствует нескольким идентификаторам потока POSIX

В самом деле? Я сомневаюсь в этом. По крайней мере, если все рассматриваемые идентификаторы потоков POSIX были действительными, то есть связанный поток либо еще не был присоединен, либо, если выполняется отсоединенный поток, поток еще не завершился.

Другие вопросы по тегам