|
第六章 高級I/O函數(shù) Linux提供了很多高級的I/O函數(shù),它不是基礎(chǔ)的I/O函數(shù)(open/read) 1、創(chuàng)建文件描述符的函數(shù)比如:pipe、dup/dup2函數(shù) 2、讀寫數(shù)據(jù)的函數(shù)比如:readv/writev、sendfile、mmap/munmap、splice 和 tee 函數(shù) 3、控制 I/O 行為和屬性的函數(shù)比如:fcntl 函數(shù) pipe函數(shù)可以創(chuàng)建一個管道,管道是一種把兩個進(jìn)程之間的標(biāo)準(zhǔn)輸入和輸出連接起來的機(jī)制。從而可以實(shí)現(xiàn)讓多進(jìn)程之間進(jìn)行通信。pipe創(chuàng)建的管道是單工的,所以需要提供兩個文件描述符來操作管道。其中一個進(jìn)行寫操作,另外一個進(jìn)行讀操作。管道的讀寫和一般的i/o read write 邏輯一致。 1、pipe 創(chuàng)建管道 int pipe (int filedes[2]) pipe 創(chuàng)建管道參數(shù)數(shù)組包含pipe使用的兩個文件描述符。 fd[0] 用于讀管道,fd[1] 用于寫管道。在創(chuàng)建管道的時候必須在fork()中調(diào)用pipe().否則子進(jìn)程不會繼承文件描述符。兩個進(jìn)程不共享祖先進(jìn)程。就不能在使用pipe().但是可以使用命名管道。 由于pipe是單工的,如果要實(shí)現(xiàn)雙向管道數(shù)據(jù)傳輸。就應(yīng)該使用兩個管道。默認(rèn)情況下,單工的管道描述符都是阻塞的。比如,如果read 讀取一個空的管道,則read將被阻塞。直到管道內(nèi)有數(shù)據(jù)可讀。如果用write系統(tǒng)調(diào)用往一個已滿的管道中寫入數(shù)據(jù),則write將被阻塞。直到管道內(nèi)有足夠的空閑空間下來才能用。那么如果將fd 都設(shè)置為非阻塞。則read 和write 會有不同的行為。如果寫端文件描述符fd[1] 的引用計數(shù)減少至0 則沒有進(jìn)程需要往管道中寫入,則 讀文件描述符fd[0] 將讀到 0 和 文件結(jié)束標(biāo)記(EOF)。如果讀文件描述符fd[0] 的引用計數(shù)減少到0 則沒有任何進(jìn)程需要從管道讀取數(shù)據(jù),則寫端文件描述符fd[1] 的write將失敗。并引發(fā)SIGPIPE信號。另外 socket 的基礎(chǔ)api 提供了創(chuàng)建雙向管道。socketpair 函數(shù)可以實(shí)現(xiàn)。 管道內(nèi)傳輸?shù)臄?shù)據(jù)都是字節(jié)流。和TCP字節(jié)流類似,但是不一樣。應(yīng)用程序能往TCP連接中寫入多少字節(jié)流的數(shù)據(jù)。取決于對方的接收通告窗口的大小和本端的擁塞窗口大小。而管道本身擁有一個容量限制。通過 fcntl 函數(shù)可以修改管道容量。 2、dup 函數(shù)和 dup2 函數(shù) dup 函數(shù)和dup2 函數(shù)都是用于復(fù)制文件描述符。dup 返回的文件描述符是取系統(tǒng)當(dāng)前最小的整數(shù)值,dup2返回第一個不小于file_descriptor_two的整數(shù)值。 3、readv 函數(shù)和 writev 函數(shù) readv 函數(shù)將數(shù)據(jù)從文件描述符讀到分散的內(nèi)存塊中,即分散讀。 writev 函數(shù)則將多塊分散的內(nèi)存數(shù)據(jù)一并寫入文件描述符中,即集中寫。 ssize_t readv(int fd, const struct iovec* vector, int count); ssize_t writev(int fd, const struct iovec* vector, int count); fd 被操作的文件描述符,vector 一塊內(nèi)存區(qū),count 是內(nèi)存區(qū)的長度,即多少塊內(nèi)存數(shù)據(jù)需要從 fd 讀出或?qū)懙?fd 4、sendfile 函數(shù) sendfile 函數(shù) 在兩個文件描述符之間直接傳遞數(shù)據(jù)。從而避免內(nèi)核緩存區(qū)和用戶緩存區(qū)之間的數(shù)據(jù)拷貝,效率高,稱零拷貝。 5、mmap 函數(shù) 和 munmap 函數(shù) mmap用于申請一段內(nèi)存空間。我們可以將這段內(nèi)存作為進(jìn)程間通通信的共享內(nèi)存。也可以將文件直接映射到其中。munmap 函數(shù)釋放由mmap創(chuàng)建的這段內(nèi)存空間。 6、splice 函數(shù) splice 函數(shù)用于在兩個文件描述符之間移動數(shù)據(jù),也是零拷貝操作。 7、tee 函數(shù) tee 函數(shù)在兩個管道文件描述符之間復(fù)制數(shù)據(jù)。也是零拷貝操作。也不消耗數(shù)據(jù),因此源文件描述符上的數(shù)據(jù)仍然可以用于后續(xù)的讀操作。 8、fcntl 函數(shù) fcntl 函數(shù) 提供了對文件描述符的各種控制操作。另外一個常見的控制文件描述符屬性和行為的系統(tǒng)調(diào)用是ioctl. 而 ioctl 比 fcntl 能夠執(zhí)行更多的控制。但是fcntl 函數(shù)是 POSIX 規(guī)范指定的首選方法。 來源:https://www./content-3-308551.html |
|
|