在 Linux 下使用 GCC 編譯多執行緒程式時,常遇到連結階段錯誤:
/tmp/ccXXXXXX.o: In function `main':
thread.c:(.text+0x2a): undefined reference to `pthread_create'
/tmp/ccXXXXXX.o: In function `main':
thread.c:(.text+0x45): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
pthread 執行緒庫不是 GCC 預設連結的標準庫。 Linux 系統將執行緒相關函數放在獨立的靜態庫 libpthread.a(或動態庫 libpthread.so)中。呼叫 pthread_create()、pthread_join()、pthread_mutex_lock() 等 API 時,必須明確告知連結器連結此庫。
gcc thread.c -o thread -lpthread
-lpthread:告訴連結器搜尋並連結 libpthread 庫-lpthread 必須放在原始檔 之後,否則連結器可能忽略未解析的符號// thread.c
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void* worker(void* arg) {
printf("Thread %ld running\n", (long)arg);
sleep(1);
return NULL;
}
int main() {
pthread_t tid[2];
for (long i = 0; i < 2; i++) {
if (pthread_create(&tid[i], NULL, worker, (void*)i) != 0) {
perror("pthread_create");
return 1;
}
}
for (int i = 0; i < 2; i++) {
pthread_join(tid[i], NULL);
}
printf("All threads finished\n");
return 0;
}
$ gcc thread.c -o thread -lpthread
$ ./thread
Thread 0 running
Thread 1 running
All threads finished
| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
gcc -lpthread thread.c -o thread | 庫在原始檔前,符號未解析 | gcc thread.c -o thread -lpthread |
忘記 #include <pthread.h> | 編譯警告:隱式宣告函數 | 務必包含標頭檔 |
使用 -pthread 代替 -lpthread | 兩者在現代 GCC 多等效,但 -pthread 還會設定預處理器巨集 | 建議統一用 -pthread(GCC/Clang 推薦) |
# 推薦寫法(GCC 4.2+ / Clang)
gcc -pthread thread.c -o thread
-pthread 同時處理編譯期(定義 _REENTRANT 等巨集)與連結期#include <pthread.h>?-lpthread 或 -pthread?glibc-devel / libc6-dev(含 pthread 標頭檔與庫)?find_package(Threads REQUIRED) + target_link_libraries(target Threads::Threads)undefined reference to pthread_join → 同樣需連結 pthreadundefined reference to pthread_mutex_init → 同樣需連結 pthreadundefined reference to sem_init → 需 -lpthread(POSIX 信號量屬 pthread)