用于创建文件描述符的函数:pipe, dup, dup2
用于读写数据的函数:readv, writev, sendfile, mmap, munmap, splice, tee
用于控制I/O行为和属性的函数:fcntl
1.pipe函数
int pipe(int fd[2]);
pipe函数可用于创建一个管道,以实现进程间通信。
通过pipe函数创建的这两个文件描述符fd[0]和fd[1]分别构成管道的两端,往fd[1]写入的数据可以从fd[0]读出。
并且fd[0]只能用于从管道中读出数据,fd[1]从管道中写入数据。默认两个文件描述符都是阻塞的。
应用程序能往一个TCP连接中写入多少字节的数据,取决于对方的接收窗口的大小和本端的拥塞窗口的大小。而管道本身拥有一个容量限制,
规定了如果应用程序不将数据从管道读走的话,该管道最多能被写入多少字节的数据。默认大小为65536字节。
int socketpair(int domain, int type, int protocol, int fd[2]); //创建双向管道。
2. dup函数和dup2函数
int dup(int file_descriptor);
int dup2(int file_descriptor_one, int file_descriptor_two);
dup函数创建一个新的文件描述符,该新文件描述符和原有的文件描述符file_descriptor指向相同的文件、管道或者网络连接。
dup总是返回系统中最小的可用文件描述符。dup2返回第一个不小于file_descriptor_two的整数值。
3.readv函数和writev函数
ssize_t readv(int fd, const struct iovec* vector, int count); //将数据从文件描述符读到分散的内存块中, 即分散读。
ssize_t writev(int fd, const struct iovec* vector, int count); //将多块分散的内存数据一并写入文件描述符中,即集中写。
4. sendfile函数
sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了内核缓冲区和用户缓冲区之间的数据拷贝,效率很高。称为零拷贝。
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之间传输的字节数。
in_fd必须是一个支持类似mmap函数的文件描述符,即它必须指向真实的文件,不能是socket和管道:而out_fd则必须是一个socket。
5.mmap函数和munmap函数
mmap函数用于申请一段内存空间,可以将这段内存作为进程间通信的共享内存,也可以将文件直接映射到其中。munmap释放该空间。
void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset);
void* munmap(void* start, size_t length);
flags参数:MAP_SHARED, 在进程中共享这段内存,对该内存的修改将反映到被映射的文件中,提供了进程间共享内存的POSIX方法。
6.splice函数
splice函数用于在两个文件描述符之间移动数据,也是零拷贝操作。
ssize_t splice(int fd_in, loff_t* off_in, int fd_out, loff_t* off_out, size_t len, unsigned int flags);
fd_in, fd_out必须至少一个为管道描述符。返回移动字节的数量。0表示没有移动。
7.tee函数
tee函数在两个管道文件描述符之间复制数据,也是零拷贝操作。不消耗数据,因此源文件描述符上数据仍然可以用与后续的读操作。
ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);
8. fcntl函数
提供了对文件描述符的各种控制操作。
int fcntl(int fd, int cmd, ...);
将一个文件描述符设置为非阻塞的:
int setnonblocking(int fd) { int old_option = fcntl(fd, F_GETFL); int new_option = old_option | O_NONBLOCK; fcntl(fd, F_SETFL, new_option); return old_option; }