背景:在muduo网络库源码中出现了两个read函数,一个是read另一个是readv,源码如下 :
1 ssize_t sockets::read(int sockfd, void *buf, size_t count) 2 { 3 return ::read(sockfd, buf, count); 4 } 5 6 ssize_t sockets::readv(int sockfd, const struct iovec *iov, int iovcnt) 7 { 8 return ::readv(sockfd, iov, iovcnt); 9 }
下面来说一下这两个函数的区别:
这两个函数类似于read和write,不过readv和writev允许单个系统调用读入到或写出自一个或多个缓冲区。这些操作分别称为分散读(scatter read)和集中写(gather write),因为来自读操作的输入数据被分散到多个应用缓冲区中,而来自应用缓冲区的输出数据则被集中提供给单个写操作。
#include <sys/uio.h> ssize_t readv(int filedes, const struct iovec *iov, int iovcnt); ssize_t writev(int filedes, const struct iovec *iov, int iovcnt); 返回:读入或写出字节数——成功;-1——出错
这两个函数的第2个参数都是指向某个iovec结构数组的一个指针,其中iovec结构在头文件<sys/uio.h>中定义:
struct iovec { void *iov_base; /* starting address of buffer */ size_t iov_len; /* size of buffer */ };
iovcnt用来说明结构数组iovec中元素的个数。iovec结构数组中元素的数目存在某个限制(IOV_MAX),具体取决于实现。POSIX要求在头文件<sys/uio.h>中定义IOV_MAX常值,而且其值至少为16。
readv和writev这两个函数可以用于任何描述字,而不仅限于套接口。另外,writev是一个原子操作,意味着对于一个基于记录的协议(例如UDP)而言,一次writev调用只产生单个UDP数据报。