我知道pthread_self()
和syscall(SYS_gettid)
之間的difference。 pthread_create()
產生一個POSIX線程ID,它由一個struct pthread_t表示,它通常被定義爲一個unsigned long int
。我們可以使用pthread_self
來獲得pthread_create
生成的ID of the thread。Posix線程ID與linux線程ID是否有一對一的關係?
隨着strace
,我知道pthread_create()
在libpthread.so.0是通過調用clone
系統調用,這也是用於fork()
系統調用來實現。通過調用pthread_create()
創建POSIX線程後,會生成一個新的POSXI線程(由pthread_self()
返回的線程ID標識)和一個新的Linux線程(由線程標識由syscall(SYS_gettid)
返回)。這是否意味着POSIX線程ID與linux線程ID具有一對一的關係?它們分別代表pthread_t
和pid_t
的線程?
實際上,有時我發現一個linux線程ID在同一個進程中映射到多個POSIX線程ID,這意味着在通過調用pthread_create()
產生一對POSIX線程ID和linux線程ID後,POSIX線程ID改變linux線程ID保持不變。有沒有辦法改變POSIX線程ID,同時保持linux線程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 .. 0.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
的調用者是根據linux線程ID(12848)的1
的結果,但它們具有不同的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;
}
標記「linuxthreads」在上下文中似乎是錯誤的,因爲「linuxthreads」與POSIX線程不同。 – alk
@alk這是否意味着Linux內核線程?如果不合適,我可以刪除這個標籤。 – Chalex
關於在Linux上進行線程化的歷史:http://www.drdobbs.com/open-source/nptl-the-new-implementation-of-threads-f/184406204(閱讀可能會使不同的字眼清晰) – alk