基礎:作業系統是什麼

API 與系統呼叫的區別

當你寫程式時,你幾乎從不親自做原始的系統呼叫;你呼叫的是函式庫裡某個友善的函式,由那個函式替你抵達核心。你呼叫的 API 與底層的系統呼叫之間的區別,是初學者常見的困惑來源,釐清它便能說明程式究竟如何與作業系統對話。想像用外送 app 點餐:你點下一個整齊的按鈕(API),幕後 app 打電話給餐廳並安排外送員(系統呼叫)。你只與按鈕互動;雜亂的真實工作在看不見的地方進行。

API(應用程式介面)是給程式設計師呼叫的一組函式,有明確定義的名稱、參數與回傳值——例如 C 標準函式庫的 fopen 與 fread,或某語言的讀檔函式。系統呼叫則是真正進入核心的請求。常常一個 API 函式對應一個系統呼叫(函式庫的 read 包裝函式,本質上就是觸發 read 系統呼叫)。但對應並非一對一:像 fprintf 這樣單一的 API 呼叫,可能把你的文字加緩衝,只偶爾才發出一次真正的 write 系統呼叫;而某些 API 函式(例如在記憶體中排序一個陣列)根本不做任何系統呼叫,因為它不需要核心幫忙。API 是你撰寫程式時所依循的合約;系統呼叫則是真正需要跨越時,跨進核心的那個機制。

為何偏好 API 而非直接做系統呼叫?可攜性與便利。同一個 API 可以在不同的作業系統上、用不同的底層系統呼叫來實作,於是你的程式能跨平台編譯與執行,而你不必知道每個核心確切的系統呼叫編號與慣例。函式庫也處理那些繁瑣的細節——包裝引數、加緩衝、重試被中斷的呼叫、以統一的方式回報錯誤。誠實的細節是:這道邊界並非總是整潔——看起來相同的 API 函式,在不同系統上可能有微妙不同的行為,而追查效能或正確性的問題,有時意味著要越過 API,去看它真正發出的系統呼叫(一個能列出它們的工具,例如系統呼叫追蹤器,就是你窺看的方法)。

你呼叫 fread() 來讀一筆記錄。函式庫也許早已用一次 read() 系統呼叫,把一大塊資料拉進它自己的緩衝區,現在直接從那緩衝區把位元組交給你,完全沒有跨入核心。一次 API 呼叫,對應零次或一次系統呼叫——它們不是同一回事。

API 呼叫與系統呼叫相關但不相同;函式庫在兩者之間搭橋。

初學者常把函式庫函式說成系統呼叫。API 是你撰寫程式所依循的對象,且可攜;系統呼叫是底層跨入核心的機制,且因作業系統而異。

又稱
application programming interface vs syscalllibrary call vs system call函式庫呼叫與系統呼叫