為什麼(UNIX/Linux)I/O函數被設計成對中斷敏感?

或者說大部分的系統調用都是中斷(信號)敏感的。

* 中斷敏感意思是指,這些函數在被中斷的時候,會產生特殊返回值或者輸出結果。大多數系統調用都會拋出EINTR,如read, write, select, poll, IPC系列等等。而一般的非系統調用則不會因為出現中斷而產生不同的返回值或者輸出結果,如字元串系列函數。


實際上大多數系統調用都是中斷敏感的,只是阻塞調用的時間是不受限的,所以一般觀測到這個問題都是在阻塞調用的情況中。而大多數阻塞調用都是 IO 調用。

與其說「設計」成中斷敏感,不如說偷懶弄成了對中斷敏感。這個問題歷史上叫 PC loser-ing problem,在 The Rise of ``Worse is Better 裡面有很詳細的說過。大意是:

  • 首先,因為中斷處理函數是 user space 的,遇到中斷時就必須立即從系統調用 (kernel space) 裡面跳出來。
  • 正確的做法是,撤銷當前系統調用已經造成的副作用,把棧上保存的 PC 寄存器回退一格(即回調到系統調用前的指令),然後再返回。
  • Unix 實現者覺得這樣做太麻煩,就直接返回了一個 EINTR。如果用戶程序要處理這種情況,就得自己寫一個 loop。


推薦閱讀:

知乎將如何做開放?
ApiTestEngine QuickStart
Web API介面如何防止本網站/APP以外的調用?
介紹幾款常用的在線API管理工具
對 echo 框架進行統一的自定義錯誤處理

TAG:設計 | API | Linux | Unix |