APUE讀書筆記-第14章-高級I/O

14.1 引言

*高級I/O包括非阻塞I/O、記錄鎖、系統V流機制、I/O多路轉換(select和poll函數)、readv和writev函數以及存儲映射I/O(mmap)


14.2 非阻塞I/O

*非阻塞I/O使我們可以調用open、read和write這樣的I/O操作,並使這些操作不會永遠阻塞


14.3 記錄鎖

*記錄鎖(record locking)的功能是:當一個進程正在讀或修改文件的某個部分時,它可以組織其他進程修改同一文件區

*考慮數據庫訪問例程庫。如果該庫中所以函數都以一致的方法處理記錄鎖,則稱使用這些函數訪問數據庫的任何進程集爲合作進程(cooperating process)。

*建議性鎖並不能阻止對數據庫文件有寫權限的任何其他進程對數據庫文件進行隨意的寫操作

*強制性鎖使內核對每一個open、read和write系統調用都進行檢查,檢查調用進程對正在訪問的文件是否違背了某一把鎖的作用。強制性鎖有時也被稱爲強迫方式鎖(enforcement-mode locking)

*如果一個進程試圖讀、寫一個強制性鎖起作用的文件,而欲讀、寫的部分又由其他進程加上了讀或寫鎖,此時會發生什麼呢?對這一問題的回答取決於三方面的因素:操作類型(read或write),其他進程保有的鎖的類型(讀鎖或寫鎖),以及有關描述符是阻塞還是非阻塞的


14.4 STREAMS

*流在用戶進程和設備驅動程序之間提供了一條全雙工通路。流無需和實際硬件會話,流也可以用來構造僞設備驅動程序

*任意數量的處理模塊可以壓入流。我們使用術語壓入,是因爲每一新模塊總是插到流首之下,而將以前的模塊下壓(這類似於後進先出的棧)

*ioctl的第二個參數request說明執行哪一個操作。所有request都以I_開始。第三個參數的作用與request有關,有時它是一個整數值,有時它是指向一個整型或一個數據結構的指針


14.5 I/O多路轉接

*問題:telnet進程有兩個輸入、兩個輸出。對這兩個輸入中的任一個都不能使用阻塞read,因爲我們永遠不知道哪一個輸入有我們需要的數據

*一種方法是仍舊使用一個進程執行該程序,但使用非阻塞I/O讀取數據。基本方法是將兩個輸入描述符都設置爲非阻塞的,對第一個描述符發一個read。如果該輸入上有數據,則讀數據並處理它;如果無數據可讀,則read立即返回。然後對第二個描述符作同樣的處理。

*一種比較好的技術是I/O多路轉換(I/O multiplexing)。先構造一張有關描述符的列表,然後調用一個函數,直到這些描述符中的一個已準備好進行I/O時,該函數才返回。在返回時,它告訴進程哪些描述符已準備好可以進行I/O


14.6 異步I/O

*除了調用ioctl說明產生SIGPOLL信號的條件以外,還應爲該信號建立信號處理程序。對於SIGPOLL的默認動作是終止該進程,所以應當在調用ioctl之前建立信號處理程序


14.7 readv和writev函數

*readv和writev函數用於在一次函數調用中讀、寫多個非連續緩衝區。有時也將這兩個函數稱爲散佈讀(scatter read)和聚集寫(gather write)


14.8 readn和writen函數

*管道、FIFO以及某些設備,特別是終端、網絡和STREAMS設備有下列兩種性質:

(1)一次read操作所返回的數據可能少於所要求的數據,即使還沒達到文件尾端也可能是這樣。這不是一個錯誤,應當繼續改設備

(2)一次write操作的返回值也可能少於指定的字節


14.9 存儲映射I/O

*存儲映射I/O(Memory-mapped I/O)使一個磁盤文件與存儲空間中的一個緩衝區相映射

*mmap函數實現就告訴內核將一個文件映射到一個存儲區域中

*void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);

*addr參數用於指定映射存儲區的起始地址

*len是映射字節數

*prot參數說明對映射存儲區的保護要求。對指定映射存儲區的保護要求不能超過文件open模式訪問權限

*flag參數影響映射存儲區的多種屬性

*filedes指定要被映射文件的描述符

*off是要映射字節在文件中的起始偏移量


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章