2015-10-19 41 views
4

我目前是一名學生,學習操作系統和使用Linux作爲操作系統。當我們到了多線程應用程序,並開始與他們(主要是剛在pthread_create(),並在pthread_join())到實踐中,最常見的錯誤類得到的一個是,編譯時使用的是:爲什麼在Linux中沒有庫說明符時沒有錯誤?

gcc -Wall homework.c 

代替的:

gcc -Wall -lpthread homework.c 

我的問題是,爲什麼不編譯時編譯器和鏈接不要拋出一個錯誤/用,即使在代碼中使用的功能需要並行線程庫-lpthread符鏈接。我的導師似乎也不知道原因。這只是學校建立我們系統的方式嗎?所有Linux環境都會發生這種情況嗎?爲什麼沒有引發鏈接器錯誤?

+1

注意'pthread'是怎樣的一個特殊* *庫,正確的參數'gcc'是'-pthread',不'-lpthread'。仍然有趣的問題。 –

+1

根據@ FelixPalmen的回答,最好給出一個示例代碼,可以重現這個問題 - 當沒有給出'-pthread'選項時,不存在編譯器/鏈接器錯誤。請從'gcc --version'提交您正在使用的GCC版本,因爲這些細節是特定於實現的。它也可能取決於你使用的是哪個版本的glibc。 –

+0

使用'gcc -v -Wall homework.c'來找出'gcc'在做什麼... –

回答

2

無法重現:

#include <pthread.h> 

void *thread(void *arg) 
{ 
    (void) arg; 
    return 0; 
} 

int main(void) 
{ 
    pthread_t t; 
    pthread_create(&t, 0, thread, 0); 
    return 0; 
} 

試圖鏈接不libpthread

> gcc -Wall -o thread thread.c 
/tmp/ccyyu0cn.o: In function `main': 
thread.c:(.text+0x2e): undefined reference to `pthread_create' 
collect2: error: ld returned 1 exit status 

編輯:您可以檢查在庫中定義的符號與nm -D,例如在我的情況:

> nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep pthread_create 
> nm -D /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create 
00000000000082e0 T pthread_create 

(所以pthread_createlibc沒有發現,但確實是在libpthread

EDIT2:唯一可能的原因是您要求遵守將是一個行爲鏈接的默認libc,或許libgcc)定義pthread_create。那麼它可能仍然依賴於僅在libpthread中定義的事物。我現在想知道這是否是某些特定版本的情況。請提供反饋。

0

加法假設@ FelixPalmen的答案。 pthread可以按照gcc的規範聲明傳遞給鏈接器。 gcc可以使用內置的規格或從文件中讀取。

實驗

默認情況下,在我的系統鏈接打印錯誤,而我嘗試建立樣品不-lpthreads

[email protected]:~$ gcc ./thread.c -o thread 
/tmp/ccHgCRzO.o: In function `main': 
thread.c:(.text+0x29): undefined reference to `pthread_create' 
collect2: error: ld returned 1 exit status 

首先我發現which files gcc tries to use as spec

[email protected]:~$ strace gcc 2>&1 | grep spec 
access("/usr/lib/gcc/i686-linux-gnu/5/specs", R_OK) = -1 ENOENT (No such file or directory) 
access("/usr/lib/gcc/i686-linux-gnu/5/../../../../i686-linux-gnu/lib/i686-linux-gnu/5/specs", R_OK) = -1 ENOENT (No such file or directory) 
access("/usr/lib/gcc/i686-linux-gnu/5/../../../../i686-linux-gnu/lib/specs", R_OK) = -1 ENOENT (No such file or directory) 
access("/usr/lib/gcc/i686-linux-gnu/specs", R_OK) = -1 ENOENT (No such file or directory) 

然後創建我自己的規格getting build-in one並將其放入上一步獲得的路徑:

[email protected]:~$ sudo gcc -dumpspecs >/usr/lib/gcc/i686-linux-gnu/5/specs 

我插入逐個-lpthread成Spec文件的*link:*lib:*libgcc:部分。在所有情況下,海灣合作委員會可以建立程序,而無需明確提及pthread庫:

[email protected]:~$ gcc ./thread.c -o thread && echo "completed" 
completed 

Gotcha !!!

檢測,如果GCC使用任何附加的規格文件

需要看接下來的輸出(I用gcc-5.1.0):

[email protected]:~$ gcc -v 2>&1 | head -1 
  • 如果GCC使用從特定文件規範你會看到下一個:

    Reading specs from /usr/lib/gcc/i686-linux-gnu/5/specs 
    
  • 否則:

    Using built-in specs. 
    

    你可以看到內置的規格做這個:

    [email protected]:~$ gcc -dumpspecs 
    

檢測是否有並行線程的連接是默認

需要看到裏面得到規範文件的-lpthread任何外觀與鏈接器相關的部分。

Spec file reference

相關問題