背景:在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數據報。