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