Linux系統呼叫解析
阿新 • • 發佈:2019-02-16
#include<linux/unistd.h> /*定義巨集_syscall1*/ #include<time.h> /*定義型別time_t*/ _syscall1(time_t,time,time_t *,tloc) /*巨集,展開後得到time()函式的原型*/ main() { time_t the_time; the_time=time((time_t *)0); /*呼叫time系統呼叫*/ printf("The time is %ld\n",the_time); } 系統呼叫time返回從格林尼治時間1970年1月1日0:00開始到現在的秒數。 這是最標準的系統呼叫的形式,巨集_syscall1()展開來得到一個函式原型。但事實上,如果把程式改成下面的樣子,程式也可以執行得同樣的結果。 #include<time.h> main() { time_t the_time; the_time=time((time_t *)0); /*呼叫time系統呼叫*/ printf("The time is %ld\n",the_time); }
這是因為在time.h中實際上已經用庫函式的形式實現了time這個系統呼叫,替我們省掉了呼叫_syscall1巨集展開得到函式原型這一步。
大多數系統呼叫都在各種C語言函式庫中有所實現,所以在一般情況下,我們都可以像呼叫普通的庫函式那樣呼叫系統呼叫,只在極個別的情況下,我們才有機會用到_syscall*()這幾個巨集。
- 呼叫效能問題
系統呼叫需要從使用者空間陷入核心空間,處理完後,又需要返回使用者空間。其中除了系統呼叫服務例程的實際耗時外,陷入/返回過程和系統呼叫處理程式(查系統呼叫表、儲存\恢復使用者現場)也需要花銷一些時間,這些時間加起來就是一個系統呼叫的響應速度。系統呼叫不比別的使用者程式,它對效能要求很苛刻,因為它需要陷入核心執行,所以和其他核心程式一樣要求程式碼簡潔、執行迅速。幸好Linux具有令人難以置信的上下文切換速度,使得其進出核心都被優化得簡潔高效;同時所有Linux系統呼叫處理程式和每個系統呼叫本身也都非常簡潔。
絕大多數情況下,Linux系統呼叫效能是可以接受的,但是對於一些對效能要求非常高的應用來說,它們雖然希望利用系統呼叫的服務,但卻希望加快相應速度,避免陷入/返回和系統呼叫處理程式帶來的花銷,因此採用由核心直接呼叫系統呼叫服務例程,最好的例子就HTTPD——它為了避免上述開銷,從核心呼叫socket等系統呼叫服務例程。
- Linux系統呼叫列表
程序控制
fork 建立一個新程序 clone 按指定條件建立子程序 execve 執行可執行檔案 exit 中止程序 _exit 立即中止當前程序 getdtablesize 程序所能開啟的最大檔案數 getpid 獲取程序標識號 modify_ldt 讀寫程序的本地描述表 nanosleep 使程序睡眠指定的時間 nice 改變分時程序的優先順序 pause 掛起程序,等待訊號 personality 設定程序執行域 prctl 對程序進行特定操作 ptrace 程序跟蹤 sched_get_priority_max 取得靜態優先順序的上限 sched_get_priority_min 取得靜態優先順序的下限 sched_getparam 取得程序的排程引數sched_getscheduler 取得指定程序的排程策略 sched_rr_get_interval 取得按RR