第六章 高级IO函数
Linux提供了很多高级的IO函数, 与网络编程相关的主要分为三类:
- 用于创建文件描述符的函数, 包括pipe, dup/dup2函数
- 用于读写数据的函数, 包括readv/writev, sendfile, mmap/munmap, splice 和 tee函数
- 用于控制IO行为和属性的函数, 包括fcntl函数
6.1 pipe函数
1 |
|
- pipe函数可以创建一个管道, 以实现进程间通信.
- 函数成功时返回0, 并将一对打开的文件描述符值填入数组, fd[0]和fd[1]分别构成管道的两端, 往fd[1]写入的数据可以从fd[0]中读取, 不能反过来. 默认情况下, 这一对文件描述符都是阻塞的.
- 如果我们用read系统调用来读取一个空的管道,则read将被阻塞,直到管道内有数据可读:如果我们用write系统调用来往一个满的管道中写入数据,则wite亦将被阻塞,直到管道有足够多的空闲空间可用。
- 如果管道的写端文件描述符fd[1]的引用计数减少至0,即没有任何进程需要往管道中写人数据,则针对该管道的读端文件描述符fd[0]的read操作将返回O,即读取到了文件结束标记(End Of File,EOF);反之,如果管道的读端文件描述符f[0]的引用计数减少至0,即没有任何进程需要从管道读取数据,则针对该管道的写端文件描述符fd[1]的wite操作将失败,并引发SIGPIPE信号。
6.2 dup函数和dup2函数
1 | int dup(int file_descriptor); |
- dup和dup2用于复制文件描述符, 实现将标准输入重定向到一个文件or把标准输出重定向到一个网络连接等等.
- dup函数创建一个新的文件描述符,该新文件描述符和原有文件描述符file_descriptor指向相同的文件、管道或者网络连接。并且dup返回的文件描述符总是取系统当前可用的最小整数值。
- dup2和dup类似,不过它将返回第一个不小于file_descriptor_two的整数值。
6.3 readv 函数和writev函数
1 |
|
- readv函数将数据从文件描述符读到分散的内存块中,即分散读;
- writev函数则将多块分散的内存数据一并写入文件描述符中,即集中写。
- iovec描述一块内存块, count 是vector数组的长度.
- readv和writev在成功时返回读出和写入fd的字节数.
以返回文档内容的http应答为例, 应答包含状态行, 许多头部字段, 一个空行以及文档的内容, 这些内容往往存储在内存的不同位置, 我们不需要将这些内容先拼接起来再一起发送, 而是可以通过writev将他们同时写出
6.4 sendfile函数
1 |
|
- sendfile函数在两个文件描述符之间直接传递数据(完全在内核中操作), 从而避免了内核
缓冲区和用户缓冲区之间的数据拷贝,效率很高,这被称为零拷贝。 - offset 指定从读入文件流的哪个位置开始, 如果为空, 则默认从起始位置开始,
- count指定传输的字节数
- 函数成功时返回传输的字节数
1 | int filefd = open(file_name, O_RDONLD); |
6.5 mmap 函数和 munmap函数
1 |
|
mmap 函数用于申请一段内存空间, 作为进程间通信的共享内存, 也可以将文件直接映射到其中. mu则释放由mmap创建的这段内存空间.
prot 包含:
- PROT_READ: 内存段可读
- PROT_WRITE: 内存段可写
- PROT_EXEC: 内存段可执行
- PROT_NONE: 内存段不能被访问
6.6 splice函数
splice函数用于在两个文件描述符之间移动数据, 是零拷贝操作.
1 |
|
- fd_in 和 fd_out必须至少有一个是管道文件描述符.
将客户端发送的数据重新发回客户端
6.7 tee函数
tee函数在两个管道文件描述符之间复制数据, 是零拷贝操作. 它不消耗数据
1 | ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags); |
- fd_in 和 fd_out必须都是管道文件描述符
- 返回在两个文件描述符之间复制的文件数据字节数
同时输出数据到终端和文件
6.8 fcntl函数
fcntl提供对文件描述符的各种控制操作.
1 |
|
- Title: 第六章 高级IO函数
- Author: Huan Lee
- Created at : 2023-08-20 07:07:56
- Updated at : 2024-02-26 04:53:15
- Link: https://www.mirthfullee.com/2023/08/20/notion-第六章 高级IO函数-9b6df7a3/
- License: This work is licensed under CC BY-NC-SA 4.0.