2012-06-22 51 views
10

爲什麼glibc和pthread庫都定義了相同的API?這裏是快照爲什麼glibc和pthread庫都定義了相同的API?

[email protected]:/lib$ objdump -T /lib/i386-linux-gnu/libc.so.6 |grep pthread_cond_signal 
000f8360 g DF .text 00000039 GLIBC_2.3.2 pthread_cond_signal 
0012b940 g DF .text 00000039 (GLIBC_2.0) pthread_cond_signal 

[email protected]:/lib$ objdump -T /lib/i386-linux-gnu/libpthread.so.0 |grep pthread_cond_signal 
0000b350 g DF .text 0000007c (GLIBC_2.0) pthread_cond_signal 
0000af90 g DF .text 000000fc GLIBC_2.3.2 pthread_cond_signal 

回答

10

libpthread.so是的glibc的一部分太,和它們都包含 (相同) 一些符號的定義。

如果你看看pthread_create相反,你會看到,它只是在libpthread.so禮物 - 這意味着程序必須鏈接到libpthread.so實際創建線程 ,但可以在單線程程序使用互斥體和條件變量,只有鏈接到 libc.so。這對於共享內存中的進程間互斥和進程間條件變量很有用,並且用於與單獨進程 同步。 (更正感謝Zan Lynx的評論)。

即使它們都定義了符號,鏈接到libpthread.solibc.so也不是問題。 ELF鏈接器允許多個共享庫包含相同符號的定義,鏈接器將選擇它所看到的第一個並將其用於該符號的所有引用,這稱爲symbol interposition。允許定義多個符號的另一個特徵是,如果一個庫包含weak symbols,那麼它將被具有相同名稱的非弱符號覆蓋。在這種情況下 這兩個庫中的定義是相同的,所以使用 libpthread.so覆蓋哪些在libc.so中並不重要。如果您使用LD_DEBUG 和更改參數的順序給連接器 你應該能夠看到符號實際上得到在發現了庫。

還有兩個庫定義相同的符號,每個庫有兩個定義的符號,與不同的symbol versionsGLIBC_2.0GLIBC_2.3.2。此符號版本控制允許多個定義在同一個庫中共存,以便將新的,改進的函數版本添加到庫中,而不會破壞與舊實現鏈接的代碼。這允許相同的共享庫爲使用LinuxThreads和使用NPTL的應用程序的應用程序工作。鏈接到庫時引用將被綁定到的默認符號是[email protected]_2.3.2,該符號對應於該函數的NPTL實現(NPTL最初包含在glibc 2.3.2中)。較早的符號[email protected]_2.0是在提供NPTL之前的默認LinuxThreads實現。與舊版本(2.3.2以前)版本的glibc鏈接的應用程序將綁定到[email protected]_2.0,並將使用該符號。

+0

你說得對,pthread_create沒有在libc.so.6中定義。但是,爲什麼我們不會在鏈接時獲得pthread_cond_signal的多個定義錯誤? –

+0

答案更新,以描述_symbol interposition_ –

+7

我不相信這個答案是完全正確的。 glibc中的定義只是佔位符,並且對於pthread操作只有空的無作用定義。 libpthread.so中的定義覆蓋這些。這適用於想要在多線程程序中以單線程但線程安全的速度運行的庫。 –

相關問題