Linux高性能服务器编程 学习笔记④

Linux 高级 I/O 函数

pipe 函数

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

  pipe 函数将一对打开的文件描述符值填入参数指定的数组内,成功返回 0,失败返回 -1 并设置 errno。
  fd[1]写入的信息可以通过 fd[0] 读出,且是单工的,默认情况下为阻塞的。
  此外,可以通过 socketpair 函数建立基于 UNIX 本地域协议族的双向通道:

#include <sys/types.h>
#include <sys/socket.h>
int socketpair (int domain, int type, int protocol, int fd[2]);

dup & dup2 函数

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

  dup 函数创建一个新的文件描述符,将新的文件描述符指向 file_descriptor 的文件(且返回的新的文件描述符总是系统当前可用的最小值)。dup2 函数创建的新的文件描述符的值便是我们传入的第二个参数 file_descriptor_two (若文件描述符此前已经打开,则其指向的打开文件会被替换为我们想要的)。调用失败时,都会返回 -1,并设置 errno。
  注:创建的文件描述符不会继承原有属性。

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);

  这两个函数用于读写分散的内存块(iovec 类型),count 参数表示 vector 参数的长度。成功返回读写的字节数,失败时返回 -1 并设置 errno。

sendfile 函数

#include <sys/sendfile.h>
ssize_t sendfile (int out_fd, int in_fd, off_t* offset, size_t count);

  sendfile 函数在两个文件描述符之间直接传递数据(内核中操作),从而避免了在内核缓冲区和用户缓冲区之间的数据拷贝,效率很高,这被称为零拷贝
  成功时返回传输的字节数, 失败时返回 -1 并设置 errno。
  注意,sendfile 函数中的 in_fd 必须是真实文件,out_fd 必须是 socket。(几乎就是为网络传输而生的函数)

mmap & munmap 函数

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

#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 指定访问权限(PROT_READ 可读,PROT_WRITE 可写,PROT_EXEC 可执行,PROT_NONE 不能被访问),flags 控制内存段内容被修改后的行为(MAP_SHARED 在进程间共享这段内存,即修改会被反映到文件中;MAP_PRIVATE进程私有,即修改不会反映到文件中),fd 表示被映射的文件, offset 表示被映射文件内容的开始位置。
  mmap 执行成功时返回目标内存指针,失败返回 MAP_FAILED 并设置 errno。munmap 成功时返回 0,失败时返回 -1 并设置 errno。

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 表示待输入的文件描述符,off_in 表示数据偏移量,若 fd_in 是一个管道描述符则 off_in 必须设置为 NULL;fd_out 与 off_out 同理。len 表示要传输的数据长度。
  成功时返回移动的字节数量,失败则返回 -1 并设置errno。
  注意splice 函数要求 fd_in 和 fd_out 中必须有一个是管道文件描述符。(相当于通过管道进行缓冲)

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 都必须是管道描述符)。
  成功返回在两个文件描述符间复制的数据量,失败返回 - 1并设置 errno。

fcntl 函数

  fcntl (file control) 函数提供了对文件描述符的各种控制操作。

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

  fd 参数代表被操作的文件描述符,cmd 参数指定执行何种类型的操作。此处仅对网络编程中使用 fcntl 函数将一个文件描述符设置为非阻塞进行说明。

int setnoblocking(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;
}

总结

  这是我自己整理的学习笔记,主要用于自我复习。如果有大佬也看到了这个并且发现了谬误,欢迎email me at lonelytaoist@qq.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值