Linux高性能服务器编程学习笔记——高级I/O函数

高级I/O函数

网络编程常用I/O函数大致分为三类:

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

pipe函数

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

pipe函数的参数是包含两个int型整数的整数指针。该函数成功时返回0,并将一对打开的文件描述符值填入其参数指向的数组。
通过pipe函数创建的这两个文件描述符fd[0]和fd[1]分别构成管道的两端,往fd[1]写入的数据可以从fd[0]读出。并且,fd[0]只能用于从管道读出数据,fd[1]则只能用于往管道写入数据,不能反过来用。

dup函数和dup2函数

有时我们希望把标准输入重定向到一个文件,或者把标准输出重定向到一个网络连接。可通过dup和dup2函数来实现:

#include <unistd.h>
int dup( int file_descriptor );
int dup2( int file_descriptor_one, int file_descriptor_two );

readv和writev函数

readv函数将数据从文件描述符读到分散的内存中,即分散读;writev函数则将多块分散的内存数据一并写入文件描述符中,即集中写。

#include <sys/uio.h>
ssize_t readv( int fd, const struct iovec* vector, int count );
ssize_t writev( int fd, const struct iovec* vector, int count );

fd参数是被操作的目标文件描述符。vector参数的类型是iovec结构数组。count参数是vector数组的长度,既有多少快内存数据需要从fd读出或写到fd。

sendfile函数

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之间传输的字节数。sendfile成功时返回传输的字节数。
in_fd必须指向真实的文件,不能是socket和管道;而out_fd则必须是一个socket。

mmap函数和munmap函数

mmap函数用于申请一段内存空间。我们可以将这段内存作为进程间通信的共享内存,也可以将文件直接映射到其中。munmap函数则释放有mmap创建的这段内存空间。它们的定义如下:

#include <sys/mman.h>
void* mmap( void *start, size_t length, int prot, int flags, int fd, off_t offset );
int munmap( void *start, size_t length );

start参数允许用户使用某个特定的地址作为这段内存的起始地址。如果它被设置成NULL,则系统自动分配一个地址。length参数指定内存段的长度。prot参数用来设置内存段的访问权限。flags参数控制内存段内容被修改后程序的行为。fd参数是被映射文件对应的文件描述符,它一般通过open系统调用获得。offset参数设置从文件的何处开始映射。

splice函数

splice函数用于在两个文件描述符之间移动数据,也是零拷贝操作。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 );

fd_in参数是待输入数据的文件描述符。如果fd_in是一个管道文件描述符,那么off_in参数必须被设置为NULL。如果fd_in不是一个管道文件描述符,那么off_in表示从输入数据流的何处开始读取数据。
fd_out/off_out参数的含义与fd_in/off_in相同,不过用于输出数据流。len参数指定移动数据的长度;flags参数则控制数据如何移动。

tee函数

tee函数在两个管道文件描述符之间复制数据,也是零拷贝操作。不消耗数据,因此源文件描述符上的数据仍然可以用于后续的读操作。

#include <fcntl.h>
ssize_t tee( int fd_in, int fd_out, size_t len, unsigned int flags );

该函数的参数的含义与splice相同(但fd_in和fd_out必须都是管道文件描述符)。

fcntl函数

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

fd参数是被操作但文件描述符,cmd参数指定执行何种类型的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值