系統(tǒng)調(diào)用的目的是什么

系統(tǒng)調(diào)用的目的是:請求系統(tǒng)服務(wù)。操作系統(tǒng)不允許用戶直接操作各種硬件資源,因此用戶程序只能通過系統(tǒng)調(diào)用的方式來請求內(nèi)核為其服務(wù),間接地使用各種資源。

創(chuàng)新互聯(lián)公司專注于保靖網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供保靖營銷型網(wǎng)站建設(shè),保靖網(wǎng)站制作、保靖網(wǎng)頁設(shè)計、保靖網(wǎng)站官網(wǎng)定制、微信小程序定制開發(fā)服務(wù),打造保靖網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供保靖網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

由操作系統(tǒng)提供的功能,通常應(yīng)用程序本身是無法實現(xiàn)的。例如對文件進(jìn)行操作,應(yīng)用程序必需通過系統(tǒng)調(diào)用才能做到,因為只有操作系統(tǒng)才具有直接管理外圍設(shè)備的權(quán)限。又如進(jìn)程或線程間的同步互斥操作,也必需經(jīng)由操作系統(tǒng)對內(nèi)核變量進(jìn)行維護(hù)才能完成。

從下到上看一個完整的計算機(jī)系統(tǒng):物理硬件->OS內(nèi)核->OS服務(wù)->應(yīng)用程序。這里的OS內(nèi)核起到了“承上啟下”的關(guān)鍵作用,向下管理物理硬件,向上為操作系統(tǒng)服務(wù)和應(yīng)用程序提供接口,這里的接口就是系統(tǒng)調(diào)用了。

應(yīng)用程序的進(jìn)程通常在user模式下運行,當(dāng)它調(diào)用一個系統(tǒng)調(diào)用時,進(jìn)程進(jìn)入kernel模式,執(zhí)行的是kernel內(nèi)部的代碼,從而具有執(zhí)行特權(quán)指令的權(quán)限,完成特定的功能。換句話說,系統(tǒng)調(diào)用是應(yīng)用程序主動進(jìn)入操作系統(tǒng)內(nèi)核的入口。

一、系統(tǒng)調(diào)用和庫函數(shù)的區(qū)別庫函數(shù)

顧名思義是把函數(shù)放到庫里,是把一些常用到的函數(shù)編完放到一個文件里,供別人用。別人用的時候把所在的文件名用#include<>加到里面就可以了,一般放到lib文件里。

庫函數(shù)主要由兩方面提供:一是操作系統(tǒng)提供的;另一類是由第三方提供的。

系統(tǒng)提供的這些函數(shù)把系統(tǒng)調(diào)用進(jìn)行封裝或者組合,可以實現(xiàn)更多的功能,這樣的庫函數(shù)能夠?qū)崿F(xiàn)一些對于內(nèi)核來說比較復(fù)雜的操作。比如read函數(shù)根據(jù)參數(shù),直接就能讀文件,而背后隱藏的文件比如在那個磁道,那個扇區(qū),加載到那個內(nèi)存,是程序員不必關(guān)心的問題。這些操作里面也包含了系統(tǒng)調(diào)用。比如write()這個系統(tǒng)函數(shù),會調(diào)用同名的系統(tǒng)調(diào)用,來完成寫入操作。

對于第三方庫,其實和系統(tǒng)庫一樣,只是他直接利用系統(tǒng)調(diào)用的可能性要小一些,而是系統(tǒng)提供的API接口來是實現(xiàn)。比如printf,實際上調(diào)用了write()這個系統(tǒng)函數(shù)。 第三方庫函數(shù)大部分是對系統(tǒng)函數(shù)的封裝。

系統(tǒng)調(diào)用和庫函數(shù)的聯(lián)系:

事實上,系統(tǒng)調(diào)用所提供給用戶的是直接而純碎的高級服務(wù),如果想要更加人性化,具有更符合特定情況的功能,那么就要我們用戶自己定義,因此衍生了庫函數(shù),它把部分系統(tǒng)調(diào)用包裝起來。比如當(dāng)我們要用C語言打印一句話的時候,如果沒有用到庫函數(shù)printf,那么我們就需要自己實現(xiàn)就需要調(diào)用putc()和write()等這樣一些系統(tǒng)函數(shù)。顯得比較麻煩,所以系統(tǒng)調(diào)用是為了方便使用操作系統(tǒng)的接口,而庫函數(shù)則是為了人們編程的方便。

例如,在Linux操作系統(tǒng)下,C語言的庫函數(shù)printf,實際上使用了write系統(tǒng)調(diào)用;而庫函數(shù)strcpy(字符串拷貝)卻沒有使用任何系統(tǒng)調(diào)用。另外,一個系統(tǒng)的系統(tǒng)調(diào)用接口通常是能夠完成所有必需功能的最小集合,可能存在多個庫函數(shù)對同一個系統(tǒng)調(diào)用進(jìn)行封裝。例如,在Linux中,malloc、calloc和free三個庫函數(shù)底層都是調(diào)用brk系統(tǒng)調(diào)用完成的。

應(yīng)用程序、庫函數(shù)和系統(tǒng)調(diào)用的關(guān)系如下圖所示:

系統(tǒng)調(diào)用和庫函數(shù)的區(qū)別:

庫函數(shù)的調(diào)用是語言或者應(yīng)用程序的一部分,而系統(tǒng)調(diào)用則是操作系統(tǒng)的一部分。

系統(tǒng)調(diào)用是應(yīng)用程序與內(nèi)核交互的接口。人們在長期的編程中發(fā)現(xiàn)使用系統(tǒng)函數(shù)有個重大的缺點,那就是程序的移植性。例如linux提供的系統(tǒng)調(diào)用的函數(shù)和windows就不一樣。

庫函數(shù)調(diào)用則是面向應(yīng)用開發(fā)的,相當(dāng)于應(yīng)用程序的api,采用這樣的方式有很多原因:

雙緩沖技術(shù);(庫函數(shù)和系統(tǒng)調(diào)用兩層緩沖,減少系統(tǒng)調(diào)用次數(shù))移植性(封裝了不同操作系統(tǒng)的系統(tǒng)函數(shù),對外接口一致)底層調(diào)用本身存在的一些缺陷;讓api也可以有了級別和專門的工作面向;

二、CPU的內(nèi)核模式和用戶模式

通常,處理器設(shè)有兩種模式:“用戶模式”與“內(nèi)核模式”,通過一個標(biāo)簽位來鑒別當(dāng)前正處于什么模式。內(nèi)核模式可以運行所有指令,包括特權(quán)指令(主要是一些硬件管理的指令,例如修改基址寄存器內(nèi)容的指令) ,而用戶模式不能執(zhí)行特權(quán)指令。這樣的設(shè)計主要為了安全問題,即由操作系統(tǒng)負(fù)責(zé)管理硬件,避免上層應(yīng)用因錯誤設(shè)計而導(dǎo)致硬件問題。

既然只有操作系統(tǒng)能直接操作硬件,操作系統(tǒng)有必要提供接口來為應(yīng)用程序提供使用硬件功能的入口,這些接口就被稱為系統(tǒng)調(diào)用。

當(dāng)操作系統(tǒng)接收到系統(tǒng)調(diào)用請求后,會讓處理器進(jìn)入內(nèi)核模式,從而執(zhí)行諸如I/O操作,修改基址寄存器內(nèi)容等指令,而當(dāng)處理完系統(tǒng)調(diào)用內(nèi)容后,操作系統(tǒng)會讓處理器返回用戶模式,來執(zhí)行用戶代碼。

對應(yīng)CPU的內(nèi)核模式和用戶模式,進(jìn)程運行的狀態(tài)分為管態(tài)(核心態(tài))和目態(tài)(用戶態(tài))。具體請看文章:操作系統(tǒng)--用戶態(tài)和核心態(tài)

四、系統(tǒng)調(diào)用和中斷的聯(lián)系

中斷(Interrupt)通常是指在CPU內(nèi)部或外部發(fā)生了某個待處理的事件,從而CPU必需改變當(dāng)前指令的執(zhí)行順序去處理這類事件。在介紹中斷和系統(tǒng)調(diào)用的關(guān)系之前,下面先把中斷做一個分類。

中斷可以大體分為兩大類:

Asynchronous interrupts(外中斷): 由CPU外部的其它硬件產(chǎn)生,說這類中斷是異步的,意思是中斷信號可以在任意時間發(fā)射,與CPU本身的時鐘節(jié)拍沒有關(guān)系。如時鐘中斷,硬盤讀寫服務(wù)請求中斷等。

Synchronous interrupts(內(nèi)中斷/異常):在CPU內(nèi)部產(chǎn)生,說這類中斷是同步的,意思是中斷信號的發(fā)射時間一定在當(dāng)前指令執(zhí)行結(jié)束之后。一般來自CPU的內(nèi)部事件或程序執(zhí)行中的事件,如非法操作碼、地址越界、浮點溢出等。

Synchronous interrupts (異常)又分為以下若干類:

Processor-detected exceptions:處理器在執(zhí)行指令時檢測到的中斷,如除零操作。

Faults:發(fā)生了某個異常條件,但異常條件被消除后,原來的程序流程可以繼續(xù)執(zhí)行而不受任何影響,如缺頁異常。注意觸發(fā)中斷的指令會被重新執(zhí)行。

Traps:由陷入指令引起的中斷,通常用于程序調(diào)試。

Aborts:CPU內(nèi)部有重要錯誤發(fā)生,例如硬件錯誤或系統(tǒng)表值出現(xiàn)錯誤。一旦這種中斷發(fā)生,錯誤將不可恢復(fù),只能將當(dāng)前進(jìn)程終止。

Programmed exceptions:也稱為 software interrupts (軟中斷) ,由程序員的代碼主動發(fā)起的中斷,用來實現(xiàn)系統(tǒng)調(diào)用。如在Linux中,就是用int 0x80指令實現(xiàn)系統(tǒng)調(diào)用。

至此,我們發(fā)現(xiàn)了中斷與系統(tǒng)調(diào)用的關(guān)系:系統(tǒng)調(diào)用是一種特殊的中斷類型(軟中斷)。

五、內(nèi)核對于系統(tǒng)調(diào)用的處理

在x86的機(jī)器中,用一個8bit的數(shù)字(0~255)來區(qū)分各種中斷,這個數(shù)字被稱為中斷向量(vector)。其中一個中斷向量,即128 (0x80),專門被用于執(zhí)行系統(tǒng)調(diào)用。

在Linux系統(tǒng)中,存有一個系統(tǒng)表,叫做Interrupt DescriptorTable,簡稱IDT。IDT表共有256項,存放了從中斷向量到相應(yīng)處理例程(interrupt or exceptionhandler)的映射關(guān)系。當(dāng)某個中斷發(fā)生時,CPU從IDT表中查找到相應(yīng)的處理例程的地址來執(zhí)行。

系統(tǒng)調(diào)用的處理例程在IDT表中占有一項。這一項是在trap_init函數(shù)中被初始化的,如下:set_system_gate(SYSCALL_VECTOR,&system_call);。如前所述,上面代碼中的SYSCALL_VECTOR的值是128。

當(dāng)系統(tǒng)調(diào)用發(fā)生時,通過中斷機(jī)制,系統(tǒng)調(diào)用例程system_call被調(diào)用。它的執(zhí)行過程大概分為4個步驟:

1、從寄存器中取出系統(tǒng)調(diào)用號和輸入?yún)?shù),然后將這些寄存器的值壓入kernel棧中。根據(jù)系統(tǒng)調(diào)用號查找系統(tǒng)調(diào)用分派表(system call dispatch table),找到系統(tǒng)調(diào)用服務(wù)例程(一個內(nèi)核函數(shù))。

2、調(diào)用查到的系統(tǒng)調(diào)用服務(wù)例程。

3、將系統(tǒng)調(diào)用服務(wù)例程的返回值出棧,重新保存在寄存器中。

上面描述的系統(tǒng)調(diào)用例程system_call在kernel空間中執(zhí)行。在執(zhí)行前,系統(tǒng)調(diào)用號和輸入?yún)?shù)已經(jīng)存入了寄存器,這個存入過程由user空間的代碼完成。實際上,如同第一節(jié)所講,每個真正的系統(tǒng)調(diào)用基本上都有一個封裝它的庫函數(shù),一般是在這個庫函數(shù)中完成系統(tǒng)調(diào)用號和輸入?yún)?shù)的保存動作。當(dāng)系統(tǒng)調(diào)用例程system_call執(zhí)行完畢后,返回值通過寄存器再傳回user空間的庫函數(shù)。

網(wǎng)站題目:系統(tǒng)調(diào)用的目的是什么
本文網(wǎng)址:http://muchs.cn/article24/cjppce.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、品牌網(wǎng)站建設(shè)、建站公司、定制網(wǎng)站、全網(wǎng)營銷推廣網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計