什么是系統(tǒng)調(diào)用?
Linux內(nèi)核中設(shè)置了一組用于實(shí)現(xiàn)各種系統(tǒng)功能的子程序,稱為系統(tǒng)調(diào)用。用戶可以通過(guò)系統(tǒng)調(diào)用命令在自己的應(yīng)用程序中調(diào)用它們。從某種角度來(lái)看,系統(tǒng)調(diào)用和普通的函數(shù)調(diào)用非常相似。區(qū)別僅僅在于,系統(tǒng)調(diào)用由操作系統(tǒng)核心提供,運(yùn)行于核心態(tài);而普通的函數(shù)調(diào)用由函數(shù)庫(kù)或用戶自己提供,運(yùn)行于用戶態(tài)。
隨Linux核心還提供了一些C語(yǔ)言函數(shù)庫(kù),這些庫(kù)對(duì)系統(tǒng)調(diào)用進(jìn)行了一些包裝和擴(kuò)展,因?yàn)檫@些庫(kù)函數(shù)與系統(tǒng)調(diào)用的關(guān)系非常緊密,所以習(xí)慣上把這些函數(shù)也稱為系統(tǒng)調(diào)用。
為什么要用系統(tǒng)調(diào)用?
實(shí)際上,很多已經(jīng)被我們習(xí)以為常的C語(yǔ)言標(biāo)準(zhǔn)函數(shù),在Linux平臺(tái)上的實(shí)現(xiàn)都是靠系統(tǒng)調(diào)用完成的,所以如果想對(duì)系統(tǒng)底層的原理作深入的了解,掌握各種系統(tǒng)調(diào)用是初步的要求。進(jìn)一步,若想成為一名Linux下編程高手,也就是我們常說(shuō)的Hacker,其標(biāo)志之一也是能對(duì)各種系統(tǒng)調(diào)用有透徹的了解。
即使除去上面的原因,在平常的編程中你也會(huì)發(fā)現(xiàn),在很多情況下,系統(tǒng)調(diào)用是實(shí)現(xiàn)你的想法的簡(jiǎn)潔有效的途徑,所以有可能的話應(yīng)該盡量多掌握一些系統(tǒng)調(diào)用,這會(huì)對(duì)你的程序設(shè)計(jì)過(guò)程帶來(lái)意想不到的幫助。
系統(tǒng)調(diào)用是怎么工作的?
一般的,進(jìn)程是不能訪問(wèn)內(nèi)核的。它不能訪問(wèn)內(nèi)核所占內(nèi)存空間也不能調(diào)用內(nèi)核函數(shù)。CPU硬件決定了這些(這就是為什么它被稱作"保護(hù)模式")。系統(tǒng)調(diào)用是這些規(guī)則的一個(gè)例外。其原理是進(jìn)程先用適當(dāng)?shù)闹堤畛?a href="http://www.1cnz.cn/tags/寄存器/" target="_blank">寄存器,然后調(diào)用一個(gè)特殊的指令,這個(gè)指令會(huì)跳到一個(gè)事先定義的內(nèi)核中的一個(gè)位置(當(dāng)然,這個(gè)位置是用戶進(jìn)程可讀但是不可寫的)。在Intel CPU中,這個(gè)由中斷0x80實(shí)現(xiàn)。硬件知道一旦你跳到這個(gè)位置,你就不是在限制模式下運(yùn)行的用戶,而是作為操作系統(tǒng)的內(nèi)核--所以你就可以為所欲為。
進(jìn)程可以跳轉(zhuǎn)到的內(nèi)核位置叫做sysem_call。這個(gè)過(guò)程檢查系統(tǒng)調(diào)用號(hào),這個(gè)號(hào)碼告訴內(nèi)核進(jìn)程請(qǐng)求哪種服務(wù)。然后,它查看系統(tǒng)調(diào)用表(sys_call_table)找到所調(diào)用的內(nèi)核函數(shù)入口地址。接著,就調(diào)用函數(shù),等返回后,做一些系統(tǒng)檢查,最后返回到進(jìn)程(或到其他進(jìn)程,如果這個(gè)進(jìn)程時(shí)間用盡)。
具體過(guò)程如下圖所示:
如何使用系統(tǒng)調(diào)用?
先來(lái)看一個(gè)例子:
這是因?yàn)樵?a href="http://www.1cnz.cn/tags/ti/" target="_blank">time.h中實(shí)際上已經(jīng)用庫(kù)函數(shù)的形式實(shí)現(xiàn)了time這個(gè)系統(tǒng)調(diào)用,替我們省掉了調(diào)用_syscall1宏展開得到函數(shù)原型這一步。
大多數(shù)系統(tǒng)調(diào)用都在各種C語(yǔ)言函數(shù)庫(kù)中有所實(shí)現(xiàn),所以在一般情況下,我們都可以像調(diào)用普通的庫(kù)函數(shù)那樣調(diào)用系統(tǒng)調(diào)用,只在極個(gè)別的情況下,我們才有機(jī)會(huì)用到_syscall*()這幾個(gè)宏。
調(diào)用性能問(wèn)題
系統(tǒng)調(diào)用需要從用戶空間陷入內(nèi)核空間,處理完后,又需要返回用戶空間。其中除了系統(tǒng)調(diào)用服務(wù)例程的實(shí)際耗時(shí)外,陷入/返回過(guò)程和系統(tǒng)調(diào)用處理程序(查系統(tǒng)調(diào)用表、存儲(chǔ)\恢復(fù)用戶現(xiàn)場(chǎng))也需要花銷一些時(shí)間,這些時(shí)間加起來(lái)就是一個(gè)系統(tǒng)調(diào)用的響應(yīng)速度。系統(tǒng)調(diào)用不比別的用戶程序,它對(duì)性能要求很苛刻,因?yàn)樗枰萑雰?nèi)核執(zhí)行,所以和其他內(nèi)核程序一樣要求代碼簡(jiǎn)潔、執(zhí)行迅速。幸好Linux具有令人難以置信的上下文切換速度,使得其進(jìn)出內(nèi)核都被優(yōu)化得簡(jiǎn)潔高效;同時(shí)所有Linux系統(tǒng)調(diào)用處理程序和每個(gè)系統(tǒng)調(diào)用本身也都非常簡(jiǎn)潔。
絕大多數(shù)情況下,Linux系統(tǒng)調(diào)用性能是可以接受的,但是對(duì)于一些對(duì)性能要求非常高的應(yīng)用來(lái)說(shuō),它們雖然希望利用系統(tǒng)調(diào)用的服務(wù),但卻希望加快相應(yīng)速度,避免陷入/返回和系統(tǒng)調(diào)用處理程序帶來(lái)的花銷,因此采用由內(nèi)核直接調(diào)用系統(tǒng)調(diào)用服務(wù)例程,最好的例子就HTTPD——它為了避免上述開銷,從內(nèi)核調(diào)用socket等系統(tǒng)調(diào)用服務(wù)例程。
-
Linux
+關(guān)注
關(guān)注
87文章
11373瀏覽量
211294 -
系統(tǒng)調(diào)用
+關(guān)注
關(guān)注
0文章
28瀏覽量
8375
原文標(biāo)題:若想成為一名Linux下編程高手,必須能對(duì)各種系統(tǒng)調(diào)用有透徹的了解
文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
如何成為一名嵌入式C語(yǔ)言高手?
如何成為一名嵌入式C語(yǔ)言高手?
Linux下C語(yǔ)言編程入門教程
了解各種系統(tǒng)調(diào)用助你成為一名Linux下編程高手

Linux操作系統(tǒng)實(shí)用教程之如何進(jìn)行Linux系統(tǒng)下的編程管理

LINUX系統(tǒng)教程之如何在Linux系統(tǒng)下進(jìn)行編程
需要了解Linux下的文件I/O編程
Linux下系統(tǒng)調(diào)用的技巧
如何區(qū)分xenomai、linux系統(tǒng)調(diào)用/服務(wù)
Linux系統(tǒng)調(diào)用的具體實(shí)現(xiàn)原理

評(píng)論