高級I/O函數
pipe函數
pipe函數用於創建一個管道,實現進程間的通信。
#include <unistd.h>
int pipe(int pipefd[2]);
通過pipe函數創建的文件描述符fd[0]和fd[1]分別構成管道的兩端,往fd[1]寫入的數據可以從fd[0]讀出,不能反過來。管道內部傳輸的數據時字節流,和TCP字節流概念相同,但有區別,管道本身擁有一個容量限制,它規定如果應用程序不將數據從管道讀走的話,該管道最多能被寫入多少字節的數據。管道容量阿東小默認是65536字節,可以用fcntl函數來修改管道容量。
此外,socket基礎API中有一個socketpair函數,能夠方便創建雙向管道。
#include<sys/types.h> /* See NOTES*/
#include<sys/socket.h>
intsocketpair(int domain, int type, int protocol, int sv[2]);
這裡domain只能使用UNIX本地域協議族AF_UNIX,因為我們僅能在本地使用這個雙向管道。
dup函數和dup2函數
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup函數創建一個新的文件描述符,該新的文件描述符和原有的文件描述符file_descriptor指向相同的文件、管道或網絡連接。並且dup返回的文件描述符總是取系統當前可用的最小整數值。Dup2和dup類型,不過它將返回第一個不小於newfd的整數值。dup和dup2系統調用失敗時返回-1並設置errno。
通過dup和dup2創建的文件描述符並不繼承原文件描述符的屬性。
readv函數和writev函數
readv函數將數據從文件描述符督導分散的內存塊中,即分散讀。Writev函數則將多塊分散的內存數據一並寫入文件描述符中,即集中寫。定義如下:
#include <sys/uio.h>
ssize_t readv(int fd, const struct iovec*iov, int iovcnt);
ssize_t writev(int fd, const struct iovec*iov, int iovcnt);
fd是文件描述符,iov是iovec結構數組,該結構體描述一塊內存區,iovcnt參數是數組的長度。
sendfile函數
sendfile函數在兩個文件描述符之間直接傳遞數據(完全在內核中操作),從而避免了內核緩沖區和用戶緩沖區之間的數據拷貝,效率高,這被稱為零拷貝。
#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd,off_t *offset, size_t count);
in_fd參數是帶讀出內容的文件描述符,out_fd參數是帶寫入內容的文件描述符,offset參數指定從讀入文件流的哪個位置開始讀,count指定文件描述符in_fd和out_fd之間傳輸的字節數。
mmap函數和munmap函數
mmap函數用於申請一段內存空間。我們可以將這段內存作為進程通信的共享內存,也可以將文件直接映射到其中。Munmap函數則釋放由mmap創建的這段內存空間。定義如下:
#include <sys/mman.h>
void *mmap(void *addr, size_t length, intprot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);
其中,start參數允許用於使用某個特定的地址作為這段內存的起始地址。如果被設置成NULL,則系統自動分配一個地址。Length參數指定內存段的長度。Port參數用來設置內存段的訪問權限,flag參數控制內存段被修改後程序的行為。Fd參數是被映射文件對應的文件描述符。Mmap函數成功時返回指向目標內存區域的指針,失敗則返回MAP_FAILED,並設置errno。
splice函數
#include <fcntl.h>
ssize_t splice(int fd_in, loff_t *off_in,int fd_out, loff_t *off_out, size_t len, unsigned int flags);
用來控制兩個文件描述符之間的數據移動,也是零拷貝操作。Flag參數控制數據流如何移動。
tee函數
tee函數在兩個管道文件描述符之間復制數據,也是零拷貝操作。它不消耗數據,因此源文件描述符上的數據仍然可以用於後續的讀操作。Tee函數的原型如下:
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <fcntl.h>
ssize_t tee(int fd_in, int fd_out, size_tlen, unsigned int flags);
fcntl函數
fcntl函數提供了對文件描述符的各種控制操作。另外一個常見的控制文件描述符屬性和行為的系統調用時ioctl,而且ioctl比fcntl能夠執行更多的控制。
《Unix/Linux編程實踐教程》之Shell編程一 http://www.linuxidc.com/Linux/2012-12/75690.htm
《Unix/Linux編程實踐教程》之Shell編程二 http://www.linuxidc.com/Linux/2012-12/75691.htm
《Unix/Linux編程實踐教程》之管道 http://www.linuxidc.com/Linux/2012-12/75692.htm
Unix/Linux編程實踐教程【高清PDF中文版+附錄光盤+代碼】:http://www.linuxidc.com/Linux/2011-08/41374.htm