Linux 系統呼叫

2021-10-23 10:16:51 字數 3810 閱讀 1836

系統呼叫是在核心空間執行的,那麼我們就需要了解在核心中是如何標識檔案的。對於核心而言,所有開啟的檔案都通過檔案描述符(簡稱fd)引用就是標識

檔案描述符是乙個非負整數,指代被開啟的檔案,當開啟乙個現有的檔案或建立乙個新檔案時,核心向程序返回乙個檔案描述符,將其作為引數給系統呼叫的i/o操作。

posix標準要求每次開啟檔案時,必須從小到大申請檔案描述符,那麼最小的檔案描述符是幾呢?不是0,因為系統已經規定了前三個:

檔案描述符

posix名稱 (常量定義在標頭檔案)

用途stdio流

0stdin_fileno

標準輸入

stdin

1stdout_fileno

標準輸入

stdout

2stderr_fileno

標準錯誤

stderr

所以 最小的檔案描述符從3開始,即開啟第乙個檔案open()返回的檔案描述就是3。

我們可以通過指令sysctl -a | grep fs.file-max來檢視最多可以開啟多少個檔案:

同時,核心為了防止乙個程序建立多個檔案,占用檔案描述符,對單個程序建立檔案的上限也做了規定,可以用ulimit -n檢視

1、帶緩衝區的i/o

含義

就是在記憶體開闢緩衝區,當執行讀檔案操作時,先把磁碟檔案讀到緩衝區,進行一次讀取,再根據程式需要將資料給讀給變數。

【舉個栗子】庫檔案i/o函式就是帶緩衝區的,如fopen,fread等

優點:

和外存的互動次數由緩衝區大小決定,如果緩衝區大,和對外存操作少。如果進入核心讀取資料,那麼互動次數會少,因為它會盡可能地一次讀取資料。故執行速度就快,效率高。

2、不帶緩衝區的i/o

含義

就是執行i/o函式時,根據程式需求,直接將資料給變數。不帶緩衝區i/o依賴於作業系統,即系統級輸入輸出

【舉個栗子】

系統呼叫i/o,如open等

缺點

會和核心進行多次互動,所以執行速度會慢

【注意】

我們不能以偏概全,不帶緩衝區地read系統呼叫函式一定比帶緩衝區地fread庫函式速度慢,這是不對的,只有合適,沒有不好。

【舉個栗子】

read需要進行多次核心態和使用者態的互動,而fread則互動少,如果我們是順序讀取資料,那麼fread即帶緩衝區的更快,但是如果我們隨機讀取資料,這時緩衝區的作用降低,read反而速度快。所以要在一定的情景下來找最合適的。

介紹關於man的指令,方便檢視函式的資訊

指令含義

man 1 command

檢視命令的幫助手冊

man 2 系統呼叫

檢視系統呼叫手冊

man 3 庫函式

檢視庫函式的使用手冊

open()函式開啟或建立乙個檔案,函式原型為:

# include。

int open(const char* pathname,int flags,…/*mode_t*/)

引數說明:第三個引數的形式我們稱為可變引數。

pathname:表示開啟或建立檔案的路徑和名字。

flags:表示開啟檔案的方式或建立,可以選擇的引數為: 引數

含義選擇

o_rdonly

唯讀開啟

必須指定,但不能和2,3兩個引數任何乙個同時存在

o_wronly

只寫開啟

必須指定,但不能和1,3兩個引數任何乙個同時存在

o_rdwr

讀寫開啟

必須指定,但不能和1,2兩個引數任何乙個同時存在

o_creat

若檔案不存在則建立它,此時第三個引數有效

可以選擇,不要求必須有

追加到檔案末尾

可以選擇,不要求必須有

o_excl

測試檔案是否存在

如果同時指定了o_creat,而檔案存在,則會出錯,不存在建立,使得測試和建立稱為原子操作

o_trunc

如果此檔案存在,而且為唯讀或讀寫開啟,則將其長度截斷為0,即每次開啟檔案清除以前的內容

可選擇o_nonblock

如果檔案是乙個管道,特殊檔案,套接字等,則此選項為檔案的本次開啟操作和後續的i/o操作設定為非阻塞。常和et模式結合,將檔案描述符設為非阻塞

可選擇可變引數:只有當引數flags種包含o_creat建立檔案的常量時,這個引數才存在,它要指定檔案的許可權,格式為【0***】,0是乙個識別符號,讀r許可權為4,寫w許可權為2,執行x許可權為1。

返回值:成功返回當前未使用的檔案描述符,失敗返回-1。

read()函式從開啟檔案中讀取資料,函式原型為:

# includessize_t read(int files,void*buf,size_t nbytes);
引數含義:

files:檔案描述符。

buf:儲存讀取到的資料的變數

nbytes:一次讀多少位元組。

成功返回讀到的位元組,到達檔案結尾返回0,出錯返回-1.

讀到那裡,檔案偏移量就到那裡,所以以前讀過的要想再讀,需要移動檔案偏移量。

write()函式向開啟的檔案寫資料,函式原型為:

# includessize_t write(int files,const *buf,size_t nbytes);
引數含義:

files表示檔案描述符。成功返回-,失敗返回-1。

當乙個程序終止時,核心自動關閉它所有開啟的檔案,這個是close的隱式使用,不是顯式。

lseek()為乙個開啟的檔案設定其偏移值,函式原型為:

# includeoff_t lseek (int files,off_t offset,int whence)
引數說明;

files表示檔案描述符。

offset:表示偏移的位元組,可正可負和whence引數有關。

whence:表示從**開始偏移,可以取值為: 引數

含義seek_set

將該檔案的偏移量設定為距離檔案開始處offset位元組

seek_cur

將該檔案的偏移量設定為距離當前位置處offset位元組

seek_end

將該檔案的偏移量設定為距離末尾處offset位元組

返回值:成功返回新的檔案偏移量,出錯返回-1。

系統呼叫是陷入中斷,進入核心的過程,是通向作業系統本身的介面,當系統呼叫i/o函式發生時,核心將呼叫核心相關函式來實現,如(sys_read(),sys_write()等),系統呼叫時乙個從使用者態->核心態->使用者態的過程,下面我們來看一下它的過程時怎樣的:

那我們簡略的畫出這個過程,這個只是為了方便理解畫出的圖,函式和對應的呼叫號並不是核心中真正的資料。

linux 系統呼叫

使用者應用可以通過兩種方式使用系統呼叫。第一種方式是通過c庫函式,包括系統呼叫在c庫中的封裝函式和其他普通函式。圖5.2 使用系統呼叫的兩種方式 第二種方式是使用 syscall巨集。2.6.18版本之前的核心,在include asm i386 unistd.h檔案中定義有7個 syscall巨集...

Linux系統呼叫

一 實驗目的和要求 1.學習linux核心的配置和編譯 2.深入理解linux系統呼叫 3.理解arm和x86的cpu模式 系統模式 使用者模式 的不同 4.掌握核心模組的編寫方法。二 實驗器材 1.linux實驗板卡一塊 2.5v 1a電源乙個 3.microusb線一根 4.macos一台 5....

Linux系統呼叫

linux系統呼叫 系統呼叫 system call 是使用者空間訪問核心的唯一手段,除異常和陷入外,他們是核心唯一的合法入口。通常情況下應用程式是通過應用程式設計介面api來訪問函式,而不是直接使用系統呼叫來程式設計。作業系統通常是通過中斷從使用者態切換到核心態。中斷就是乙個硬體或軟體請求,要求c...