系統呼叫(system call)
/ syscall: SIS-call /
想像你是旅館的房客,想要某件只有員工能替你做的事——進入上鎖的庫房、把費用記到大樓的帳上、打開頂樓的門。你不會破門而入;你拿起電話撥給櫃台,因為櫃台擁有你所沒有的權限。系統呼叫就是你的程式撥打核心的櫃台電話,請它執行一項程式自己無權執行的操作。
精確地說:系統呼叫是使用者模式程式請核心代為執行特權操作的機制。讀檔案、向作業系統要更多記憶體、建立新行程、把資料送上網路——這些全都會碰到硬體或共用資源,所以程式在使用者模式下無法自己做。取而代之,它會備好請求(一個標明它想要哪項服務的編號,加上引數),並執行一條特殊指令陷入核心。核心檢查這個請求是否被允許、在核心模式下完成工作、把結果放在程式讀得到的地方,再把控制權交回使用者模式。從程式那一側看,它幾乎像一次普通的函式呼叫——read(fd, buf, n)——但在底下,發生了一次受控的模式切換。
為何重要:系統呼叫是每個程式與作業系統之間唯一的那道門。程式對外界所做的幾乎每一件事,最終都透過它進行。明白這點,你就能推理成本(每一次呼叫都要跨越使用者/核心邊界,這並非免費)、推理安全(核心驗證每一個請求)、以及推理可移植性(系統呼叫的確切集合是定義一個平台的一部分)。人們說某程式「和作業系統對話」時,幾乎都是指它在進行系統呼叫。
要讀一個檔案,程式會先進行 open() 系統呼叫(取得一個檔案描述符)、再進行 read() 系統呼叫(把位元組從核心複製進程式的緩衝區)、最後 close()。其中每一個都是一趟獨立的進核心之旅。
open/read/close 是三個不同的系統呼叫——三次邊界跨越。
並非每個 C 函式都是系統呼叫。printf() 和 malloc() 是函式庫函式,底下可能進行零次、一次或好幾次系統呼叫;許多函式庫呼叫完全在使用者模式下完成工作,從不進入核心。