Linux高性能服务器编程第六章高级I/O函数

Linux提供了很多高级的I/O函数,在特定条件下表现出优秀的性能,大致分为三类:

  • 用于创建文件描述符的函数:pipe、dup/dup2
  • 读写数据的函数:readv/writev、sendfile等
  • 用于控制I/O行为和属性的函数:fcntl

pipe函数

pipe函数可以用于创建一个管道,以实现进程间通信。

1
2
#include<unistd.h>
int pipe(int fd[2]);

参数是一个包含两个int型整数的数组指针,成功时返回0,并将一对打开的文件描述符填入其参数指向的数组,如果失败返回-1并设置errno

通过pipe函数创建的两个文件描述符fd[0]和fd[1]分别构成管道两端,并且f[0]只能用于读出数据,f[1]只能用于写数据

dup和dup2

dup函数创建一个新的文件描述符,该新文件描述符和原有文件描述符file_descriptor 指向相同的文件、管道或者网络连接。并且 dup返回的文件描述符总是取系统当前可用的最小整数值。dup2和 dup类似,不过它将返回第一个不小于file_descriptor_two的整数值。dup和dup2系统调用失败时返回-1并设置errno。

mmap函数

用于申请一段内存空间,可以将这段内存作为进程间通信的共享内存,也可以将文件直接映射到其中。

fcntl函数

即file control,提供了对文件描述符的各种控制操作

1
2
#include <fcntl.h>
int fcntl(int fd,int cmd, ...);

fd参数是被操作的文件描述符,cmd参数指定执行何种类型的操作,根据操作类型不同,可能需要第三个可选参数arg,具体操作如下图所示:

image-20231107111357581

image-20231107111427570

fcntl函数一般用来将一个文件描述符设置为非阻塞

1
2
3
4
5
6
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;
}