線程標識符(Thread ID)是線程在進程內的唯一標識。本文詳細講解兩種獲取方式:pthread_self()(線程內部獲取)與 pthread_create 輸出參數(創建者獲取),並演示其值的一致性。
pthread_self — 線程自我識別
#include
pthread_t pthread_self(void);
getpid()。pthread_t 類型實現定義(Linux通常為 unsigned long,但不可假設)。pthread_create 輸出參數 — 創建者獲取
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
thread 為輸出參數,創建成功後寫入新線程ID。pthread_join、pthread_cancel、pthread_kill 等操作。pthread_t 可能是整數、結構體或指針。**不可直接用 %lu 打印**。推薦做法:
// 方法1:轉為 unsigned long (Linux/glibc常見)
printf("Thread ID: %lu\n", (unsigned long)pthread_self());
// 方法2:使用 PRIuPTR (C99 ),針對指針大小整數
#include
printf("Thread ID: %" PRIuPTR "\n", (uintptr_t)pthread_self());
// 方法3:自定義打印函數(處理結構體情況)
void print_tid(pthread_t tid) {
// 簡單實現:按字節打印十六進制
unsigned char *p = (unsigned char*)&tid;
for (size_t i=0; i
#include
#include
#include
void *thread_func(void *arg) {
// 線程內部獲取
pthread_t self = pthread_self();
printf("Inside thread: pthread_self() = %lu\n", (unsigned long)self);
return NULL;
}
int main() {
pthread_t tid;
int ret = pthread_create(&tid, NULL, thread_func, NULL);
if (ret != 0) return 1;
// 創建者獲取
printf("In main: pthread_create output = %lu\n", (unsigned long)tid);
pthread_join(tid, NULL);
return 0;
}
In main: pthread_create output = 140123456789248 Inside thread: pthread_self() = 140123456789248
兩者完全一致,驗證了 pthread_create 寫入的ID與線程內部 pthread_self() 返回的ID是同一值。
pthread_join/pthread_detach 回收後,ID可被復用。ps -T -p 或 top -H -p 可查看線程(顯示為 LWP,輕量級進程ID,內核調度實體,**不等於** pthread_t)。pthread_key TLS機制)。gdb 切換線程 thread 、perf、vtune 關聯線程。pthread_kill(tid, sig) 向特定線程發信號。pthread_cancel(tid)、pthread_join(tid, ...)。pthread_t 是整數,**打印時轉型**。pthread_t 作為數組下標或哈希鍵(除非轉為整數且確認無碰撞)。pthread_self() 在 main 中調用即得,也可用 pthread_t main_tid = pthread_self(); 保存。pthread_equal(t1, t2) 是比較兩個 pthread_t 唯一可移植方式(返回非0相等)。線程ID是線程身份證。掌握 pthread_self(內省)與 pthread_create 輸出(外觀)雙路獲取,配合可移植打印與 pthread_equal 比較,即可在日誌、調試、同步、管理中精準定位每一個執行流。