前言:
本篇重點知識點:1.語言級的緩沖區設計的目的是減少系統調用,以提高效率。內核級的緩沖區是為了減少與外設的交流,提高效率。這兩個設計都是為了提高效率。
2.理解外部設備對于進程而言也是文件。Struct file中會有操作符表(函數指針的集合),它可以屏蔽不同設備直接的操作方法。也相當于文件。理解刷新,寫入緩沖區本質是拷貝。
一.理解一切皆文件1.1先描述,再組織操作系統OS對下要管理外設,對上要提供對應的接口,讓用戶進行操作。在系統調用這個層面,又給我封裝了語言層的函數。fopen,fclose……
1.1.1那么管理外設,是怎么管理的呢?——先描述,再組織對外部設備的描述,會定義一個結構體,里面包含這外設的類型,工作狀態,id值,還有其他很多的屬性。—–這樣對設備進行了描述。
每一個設備都會有結構體描述起來,他們的大方向是差不多的,有很多對應的屬性,比如名稱。只是他們的值不一樣。每個設備會串在一個鏈表中,那么到后面,我們對設備的管理,就到了對鏈表的增刪查改。
每一個外設,都有自己的驅動程序,是提供設備的廠商給我們提供的。
1.1.2描述的結構體中,有對應的操作方法linux系統是c語言寫的,C語言結構體中,不能封裝方向,那么它是怎么控制對應的設備進行運作的呢?C語言中可以封裝函數指針。
比如鍵盤有寫入的函數,輸出的函數。顯示器也有輸入的函數,也有輸出的函數。但是對應鍵盤來說,輸入函數是沒有意義的,所以就設置為空。對于顯示器來說,輸入函數是無效的,所以也設置為空。所以這樣就能保證能共用一套結構體結構。后面操作系統要進行對應的操作,也可以統一。
1.2在進程角度,一切皆文件對于普通的文件,有對應的文件描述:struct file。里面包含文件的屬性和方法。但是從上面來看,底層在進行處理以后,也是有struct file,里面包含這屬性和方法,讓不同的設備一同樣的方式描述起來,這就和文件一樣了。所以外部設備也可以理解為文件了。
我們的所以行為,全部都會被轉換為進程。當進程找到對應的文件,就可以有對應的方法,該可以調用函數進行執行了。
多個設備提供的方法就是多態。
二.文本寫入和二進制文件顯示器是字符設備,我們輸出1234(一千兩百三十四),其實是在顯式器上輸出了‘1’字符,‘2’字符,‘3’字符,‘4’字符。
2.1為什么要有printf這樣的函數?對于write系統調用而言,它要輸出的字符串是void*類型的,它沒有所謂的文本和二進制。那為什么我們還要去printf指明所對應的類型呢,比如要打印整數,我們在printf中寫%d,打印浮點數%f。就能直接打印,不然直接用write時,我們先要把整數轉化為字符串,才能打印。
所以printf是方便了我們用戶的。
在底層是不區分文件文件和二進制文件的。字符其實有對應的ACSII碼,是一個一個的二進制數字表示的字符。所以只有二進制文件。
2.2偉大的C語言不同系統的系統調用會不一樣,但是我們在寫代碼的時候,在不同的平臺基本沒有變化。不同的操作系統的底層接口是不一樣的,C語言幫我們封裝以后,讓我們不要去擔心底層,C語言在不同操作系統會有不同的處理。
提高代碼的可移植性。
C語言的庫:
一款語言,會實現不同操作系統的兼容,不同的操作系統的底層實現是不一樣的。所以就有了語言的可移植性。這也是為了增加用戶群體。
三.內核級緩沖區3.1他們是如何提高效率的呢?如果每個我們每次輸出都進行一次output,就會有很大的成本,他們一般設置的是行刷新,或者是當緩沖區滿的時候,再刷新(fflush)。
對于顯示器這樣的特殊設備,一般用的是行刷新,即遇到換行就會刷新。對于其他的文件,那么可能就是當緩沖區滿的時候,才會進行刷新。
3.2如何看待內核級緩沖區?當我們調用write接口對于文件進行寫入時,不是直接寫到文件,而是寫到文件的緩沖區。具體多久寫到文件中,由操作系統決定。所以不是每使用一次write,就會進行一次IO。而是有幾次,當緩沖區中的內容到達一定的數量時,才進行刷新。
語言級的緩存區差不多也是這樣的設計。當我們使用printf時,不會直接把我們輸出的內容直接輸出到內核級緩沖區。而是把要輸出的內容拷貝到FILE結構體的buf數組中。在滿足一定條件的時候,才會把buf數組中的調用系統調用接口,把FILE結構體中的內容拷貝到內核級緩沖區。
內核級緩沖區多久進行IO,由操作系統決定。
3.3如何讓內核級緩沖區進行刷新?fd是文件描述符。要進行寫入,這個文件肯定被打開,被打開,就肯定在文件描述符表中,fd就表示的是文件描述符表的下標。
3.4如何讀取,修改文件?上面所說的是寫入,讀取就是相反的過程。而修改就包含了讀入和修改。
讀取就包含了打開文件(如何找到文件,磁盤中的文件時如何,是文件系統的內容,在后面的文件,會進行講解),把文件的內容加載到緩沖中,然后上層從緩沖中讀取,這就形成了讀取。
而修改就是先讀取,然后把指定的內容進行修改以后,再進行寫入就可以了。
3.5內存塊緩沖區是有內存塊組成的,內存塊一般是4KB。