今天無意查資料的時候琉历,看到一篇文章What is Linux System Calls and Library Functions?硼端,在將系統(tǒng)調用和庫函數(shù)的區(qū)別亚兄,雖然這個問題是耳熟能詳?shù)拿嬖囶}低滩,但是其實大部分人還是不能很好的區(qū)分,所以就花點時間翻譯一下欺抗,方便大家學習售碳。
1.庫函數(shù) VS 系統(tǒng)調用
標準C庫的函數(shù)稱為庫函數(shù),比如一些字符串處理函數(shù)(strcmp绞呈,strlen)贸人。
系統(tǒng)調用會讓程序的運行模式從用戶態(tài)切換到內核態(tài)。在某些情況下佃声,程序需要一些只能靠內核提供的功能就需要調用艺智,比如,我們需要修改系統(tǒng)時間或者創(chuàng)建socket圾亏。
2.為什么需要系統(tǒng)調用十拣?
系統(tǒng)調用就像是一個系統(tǒng)內核的入口封拧。有一些任務需要進程跑在內核態(tài)才能執(zhí)行,比如和硬件打交道夭问。所以進程調用系統(tǒng)調用就能讓自己運行在內核態(tài)從而執(zhí)行這些類似的任務泽西。
3.庫函數(shù)類型
可分為兩類:沒有調用系統(tǒng)調用,以及調用了系統(tǒng)調用缰趋。
有一些庫函數(shù)沒有調用系統(tǒng)調用捧杉,比如strlen。有一些則會調用秘血,比如庫函數(shù)fopen內部調用了open系統(tǒng)調用味抖。
4.各組件的交互
上圖顯示了程序可以同時和庫函數(shù)或者系統(tǒng)調用交互。同樣的灰粮,一個庫函數(shù)內部也可以再調用系統(tǒng)調用仔涩。但是,只有系統(tǒng)調用有權限訪問硬件谋竖。
5.fopen VS open
有些人疑惑為什么同個操作有兩個函數(shù)红柱,比如打開文件承匣?
因為fopen提供了I/O緩存功能而open只是一個沒有緩存功能的系統(tǒng)調用蓖乘。程序應該避免直接使用open,雖然也能打開文件韧骗。
一般而言嘉抒,如果有個庫函數(shù)對應一個系統(tǒng)調用,我們需要優(yōu)先使用庫函數(shù)袍暴,因為:
a.庫函數(shù)具備可移植性些侍,可以運行在大多數(shù)不同系統(tǒng)。但是系統(tǒng)調用只是針對某個系統(tǒng)上的政模。
b.有時對應的庫函數(shù)會減少系統(tǒng)調用的負載岗宣。比如有個程序需要頻繁讀取文件,這時使用fopen就能避免每次調用都會
執(zhí)行系統(tǒng)調用淋样,因為fopen提供了緩存功能耗式。fopen可能一次性讀了比用戶需要的更多的數(shù)據(jù),因此接下來就可以不用再調用系統(tǒng)調用了趁猴。
6.malloc是系統(tǒng)調用嗎刊咳?
有個普遍的誤解認為malloc是系統(tǒng)系統(tǒng),這是錯的儡司。因為malloc只是個庫函數(shù)娱挨,內部是使用brk或者sbrk系統(tǒng)調用來實現(xiàn)內部分配。
7.系統(tǒng)調用:切換運行態(tài)
傳統(tǒng)的方式是引發(fā)“int $0x8o”中斷捕犬。內核捕獲中斷后跷坝,會把運行態(tài)從用戶態(tài)切換到內核態(tài)酵镜。
8.一些其他的不同
a.一個庫函數(shù)鏈接到用戶程序,執(zhí)行在用戶態(tài)探孝;而系統(tǒng)調用沒有鏈接到用戶程序笋婿,運行在內核態(tài);
b.一個庫函數(shù)執(zhí)行時間是計算用戶層次時間(user level time)顿颅;但是系統(tǒng)調用的運行時間是作為系統(tǒng)時間來計算的缸濒;
c.庫函數(shù)可以很方便的調試;而系統(tǒng)調用很麻煩因為運行在內核