$ gcc thread.c -o thread
/tmp/ccXXXXXX.o: In function `main':
thread.c:(.text+0x1a): undefined reference to `pthread_create'
thread.c:(.text+0x2e): undefined reference to `pthread_join'
代碼包含了 <pthread.h>,調用了 pthread_create、pthread_join,編譯預處理通過,鏈接失敗。
pthread 庫不是 GCC 默認鏈接的庫。
頭文件 pthread.h 僅提供聲明,實現位於獨立的靜態庫 libpthread.a (或動態庫 libpthread.so) 中。鏈接器需顯式指定 -lpthread 才能解析符號。
gcc thread.c -o thread -lpthread
順序很重要:-lpthread 必須放在源文件 後面 (GCC 鏈接器按順序解析符號)。
#include <pthread.h>-lpthread (或 -pthread,見下文)pthread_atfork 等函數同理需鏈接#include <stdlib.h>,實際上 pthread.h 已包含必要系統頭文件,非必需-pthread vs -lpthread| 選項 | 作用 | 推薦場景 |
|---|---|---|
-pthread | 同時影響編譯 (定義 _REENTRANT 等宏、調整線程局部存儲模型) 和鏈接 (鏈接 pthread 库) | **首選**。GCC/Clang 官方推薦,跨平台一致性最好 |
-lpthread | 僅鏈接庫 | 舊代碼維護、特殊構建系統需分離編譯/鏈接步驟 |
最佳實踐:
# 編譯+鏈接一步到位
gcc -pthread thread.c -o thread
# 或分離
gcc -pthread -c thread.c -o thread.o
gcc -pthread thread.o -o thread
find_package(Threads REQUIRED)
add_executable(my_thread thread.c)
target_link_libraries(my_thread Threads::Threads)
Threads::Threads 目標會自動處理平台差異 (Linux -pthread、Windows 無需、部分 Unix -lpthread)。
$ nm thread | grep pthread
U pthread_create
U pthread_join
$ ldd thread | grep pthread
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x...)
符號表顯示 U (未定義,來自動態庫),運行時動態鏈接器解析。
undefined reference to pthread_create 純屬鏈接缺少庫。記住口訣:「用線程,加 -pthread」。現代構建系統 (CMake/Meson) 用 Threads 包裹,一勞永逸。