我知道 和之间的区别。生成一个 POSIX 线程 ID,它由通常定义为. 我们可以用来获取生成的线程的ID。pthread_self()
syscall(SYS_gettid)
pthread_create()
unsigned long int
pthread_self
pthread_create
有了strace
,我知道pthread_create()
在libpthread.so.0中是通过调用clone
系统调用来实现的,这也是用于的系统调用fork()
。通过调用创建POSIX线程后pthread_create()
,会产生一个新的POSXI线程(由返回的线程ID标识pthread_self()
)和一个新的linux线程(由返回的线程ID标识syscall(SYS_gettid)
)。这是否意味着 POSIX 线程 ID 与 linux 线程 ID 具有一对一的关系?pthread_t
它们只是分别用和代表线程pid_t
?
实际上,有时我发现一个linux线程ID映射到同一个进程中的多个POSIX线程ID,这意味着通过调用产生一对POSIX线程ID和linux线程ID后pthread_create()
,POSIX线程ID发生变化,而linux线程ID保持不变相同的。有没有办法在保持 linux 线程 ID 不变的同时更改 POSIX 线程 ID?如果有,它pthread
是什么功能?
谢谢你。
这里是通过拦截fork
和pthread_create
调用的日志。ltid
表示linux线程ID,tid
表示POSIX线程ID,pid
表示进程ID。
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线程ID(12848)的结果,但是它们有不同的POSIX线程ID。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;
}