Имеет ли 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
Мое объяснение:
- (pid = 12832, ltid = 12832, tid = 140... 976) звонки
fork
производство (pid = 12848, ltid = 12848, tid = 140... 976) - (pid = 12848, ltid = 12848, tid = 140... 296) звонков
fork
производство (pid = 12849, ltid = 12849, tid = 140... 296) - (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 были действительными, то есть связанный поток либо еще не был присоединен, либо, если выполняется отсоединенный поток, поток еще не завершился.