【Linux系统编程】Linux系统调用
00. 目錄
文章目錄
- 00. 目錄
- 01. 系統調用概述
- 02. 系統調用實現
- 03. 系統調用和庫函數的區別
- 04. 附錄
01. 系統調用概述
系統調用顧名思義,說的是操作系統提供給用戶程序調用的一組“特殊”接口。用戶程序可以通過這組“特殊”接口來獲得操作系統內核提供的服務,比如用戶可以通過文件系統相關的調用請求系統打開文件、關閉文件或讀寫文件,可以通過時鐘相關的系統調用獲得系統時間或設置定時器等。
從邏輯上來說,系統調用可被看成是一個內核與用戶空間程序交互的接口——它好比一個中間人,把用戶進程的請求傳達給內核,待內核把請求處理完畢后再將處理結果送回給用戶空間。
系統服務之所以需要通過系統調用來提供給用戶空間的根本原因是為了對系統進行“保護”,因為我們知道 Linux 的運行空間分為內核空間與用戶空間,它們各自運行在不同的級別中,邏輯上相互隔離。所以用戶進程在通常情況下不允許訪問內核數據,也無法使用內核函數,它們只能在用戶空間操作用戶數據,調用用戶空間函數。比如我們熟悉的“hello world”程序(執行時)就是標準的用戶空間進程,它使用的打印函數 printf 就屬于用戶空間函數,打印的字符“hello word”字符串也屬于用戶空間數據。
但是很多情況下,用戶進程需要獲得系統服務(調用系統程序),這時就必須利用系統提供給用戶的“特殊接口”——系統調用了,它的特殊性主要在于規定了用戶進程進入內核的具體位置;換句話說,用戶訪問內核的路徑是事先規定好的,只能從規定位置進入內核,而不準許肆意跳入內核。有了這樣的陷入內核的統一訪問路徑限制才能保證內核安全無誤。我們可以形象地描述這種機制:作為一個游客,你可以買票要求進入野生動物園,但你必須老老實實地坐在觀光車上,按照規定的路線觀光游覽。當然,不準下車,因為那樣太危險,不是讓你丟掉小命,就是讓你嚇壞了野生動物。
02. 系統調用實現
系統調用是屬于操作系統內核的一部分的,必須以某種方式提供給進程讓它們去調用。CPU 可以在不同的特權級別下運行,而相應的操作系統也有不同的運行級別,用戶態和內核態。運行在內核態的進程可以毫無限制的訪問各種資源,而在用戶態下的用戶進程的各種操作都有著限制,比如不能隨意的訪問內存、不能開閉中斷以及切換運行的特權級別。顯然,屬于內核的系統調用一定是運行在內核態下,但是如何切換到內核態呢?
答案是軟件中斷。軟件中斷和我們常說的中斷(硬件中斷)不同之處在于,它是通過軟件指令觸發而并非外設引發的中斷,也就是說,又是編程人員開發出的一種異常(該異常為正常的異常)。操作系統一般是通過軟件中斷從用戶態切換到內核態。
中斷有兩個重要的屬性,中斷號和中斷處理程序。中斷號用來標識不同的中斷,不同的中斷具有不同的中斷處理程序。在操作系統內核中維護著一個中斷向量表(Interrupt Vector Table),這個數組存儲了所有中斷處理程序的地址,而中斷號就是相應中斷在中斷向量表中的偏移量。更多詳細說明請看《系統調用的實現原理》。
03. 系統調用和庫函數的區別
Linux 下對文件操作有兩種方式:系統調用(system call)和庫函數調用(Library functions)。
庫函數由兩類函數組成:
1) 不需要調用系統調用
不需要切換到內核空間即可完成函數全部功能,并且將結果反饋給應用程序,如strcpy、bzero 等字符串操作函數。
2)需要調用系統調用
需要切換到內核空間,這類函數通過封裝系統調用去實現相應功能,如 printf、fread等。
系統調用是需要時間的,程序中頻繁的使用系統調用會降低程序的運行效率。當運行內核代碼時,CPU工作在內核態,在系統調用發生前需要保存用戶態的棧和內存環境,然后轉入內核態工作。系統調用結束后,又要切換回用戶態。這種環境的切換會消耗掉許多時間。
庫函數訪問文件的時候根據需要,設置不同類型的緩沖區,從而減少了直接調用 IO 系統調用的次數,提高了訪問效率。緩沖區詳情請看《淺談標準I/O緩沖區》。
這個過程類似于快遞員給某個區域(內核空間)送快遞一樣,快遞員有兩種方式送:
來一件快遞就馬上送到目的地,來一件送一件,這樣導致來回走比較頻繁(系統調用)
等快遞攢著差不多后(緩沖區),才一次性送到目的地(庫函數調用)
04. 附錄
參考:【Linux】一步一步學Linux系統編程教程匯總
總結
以上是生活随笔為你收集整理的【Linux系统编程】Linux系统调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux】一步一步学Linux——n
- 下一篇: 【Linux】一步一步学Linux——l