设为首页 加入收藏

TOP

31.2. 分散/聚集 I/O
2013-10-07 00:32:12 来源: 作者: 【 】 浏览:68
Tags:31.2.分散 聚集 I/O

31.2. 分散/聚集 I/O

分散/聚集I/O涉及在I/O API和客户代码之间,以物理离散的方式交换信息。在所有我曾遇到的情况中,所谓的离散就是一组分离的内存块。以UNIX的readv()和writev()函数为例,这两个函数的行为类似于其同胞read()和write(),但read()和write()的参数是指向单个内存区域的指针,以及区域的大小,而readv()和writev()则需要传入iovec结构的数组:

struct iovec
{
void*   iov_base;
size_t  iov_len;
};
ssize_t readv(int fd, const struct iovec* vector, int count);
ssize_t writev(int fd, const struct iovec* vector, int count);
Windows Sockets API也有类似的结构和对应的函数:
struct WSABUF
{
u_long  len;
char*   buf;
};
int WSARecv(SOCKET  s
, WSABUF* lpBuffers
, DWORD   dwBufferCount
, . . . // And 4 more parameters);
int WSASend(SOCKET  s
, WSABUF* lpBuffers
, DWORD   dwBufferCount
, . . . // And 4 more parameters);
int WSARecvFrom(SOCKET  s
, WSABUF* lpBuffers
, DWORD    dwBufferCount
, . . . // And 6 more parameters);
int WSASendTo(  SOCKET  s
, WSABUF* lpBuffers
, DWORD    dwBufferCount
, . . . // And 6 more parameters);

你可能想知道,既然这种I/O方式将显著增加客户代码的复杂度,为什么人们还要采用呢?理由如下,首先如果你的文件或者网络数据采用固定格式,你就可以一次对一条或者多条记录/包执行I/O,而无需将数据来回移动、重新格式化,或者彼此拼接,这有可能带来很大的便利。与此类似,如果你的记录/包的格式可变,而首部的大小固定,你可以用匹配的结构直接读写首部,然后把剩余部分当作长度可变的不透明内存块。还有第三个原因:性能。我曾经设计了一个服务器架构,其中就使用了分散/聚集I/O,而后者又使用多线程无阻塞的内存分配方案。(毫不夸张地讲,这个架构性能优异。)

但是不论对提高性能有多大帮助,使用分散/聚集I/O是有代价的,一旦处理变长的记录/包,或者记录/包的有效载荷中包含变长元素,客户代码就变得很复杂,透明性也大多不好,还容易出错。因此一个高效的抽象必不可少。

【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇2.3.1. 需要修改迭代器精化的分类.. 下一篇2.2.1.可变性

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: