首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

線程標識符獲取與打印:pthread_self 與 pthread_create 返回值對比

     編輯:關於C語言

線程標識符獲取與打印:pthread_self 與 pthread_create 返回值對比

線程標識符(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。
  • 主線程(或創建者)即可獲得子線程ID,用於後續 pthread_join、pthread_cancel、pthread_kill 等操作。

三、打印線程ID的可移植寫法

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是同一值。

六、線程ID的作用域與生命週期

  • 作用域:僅在創建它的進程內有效。不同進程的線程ID可能重複。
  • 生命週期:線程創建時分配,線程終止並被 pthread_join/pthread_detach 回收後,ID可被復用。
  • 系統命令查看:ps -T -p 或 top -H -p 可查看線程(顯示為 LWP,輕量級進程ID,內核調度實體,**不等於** pthread_t)。

七、常見用途

  1. 日誌追蹤:多線程日誌加入TID,區分執行流。
  2. 線程專用數據:以TID為鍵存儲上下文(或用 pthread_key TLS機制)。
  3. 調試/分析:gdb 切換線程 thread 、perf、vtune 關聯線程。
  4. 信號發送:pthread_kill(tid, sig) 向特定線程發信號。
  5. 取消/加入:pthread_cancel(tid)、pthread_join(tid, ...)。

八、注意事項

  • 不要假設 pthread_t 是整數,**打印時轉型**。
  • 不要將 pthread_t 作為數組下標或哈希鍵(除非轉為整數且確認無碰撞)。
  • 主線程ID:pthread_self() 在 main 中調用即得,也可用 pthread_t main_tid = pthread_self(); 保存。
  • pthread_equal(t1, t2) 是比較兩個 pthread_t 唯一可移植方式(返回非0相等)。

線程ID是線程身份證。掌握 pthread_self(內省)與 pthread_create 輸出(外觀)雙路獲取,配合可移植打印與 pthread_equal 比較,即可在日誌、調試、同步、管理中精準定位每一個執行流。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved