设为首页 加入收藏

TOP

31.3.2. platformstl::scatter_slice_sequence—预告
2013-10-07 00:33:48 来源: 作者: 【 】 浏览:57
Tags:31.3.2. platformstl::scatter_slice_sequence 预告

31.3.2. platformstl::scatter_slice_sequence—预告

在STLSoft中,有个组件刚刚加入子项目PlatformSTL且仍在演化,名字叫做scatter_slice_sequence,它以另一种方式表达了这个抽象。这是一个Façade类模板,它维护一个数组,其元素是表示片段的结构,整个数组描述一组I/O缓冲区。该类模板除了提供STL集合风格的访问方法(通过begin()和end()),还允许调用原生read/write函数直接操作缓冲区。这个类与iovec和WSABUF都能搭配,因为通过属性垫片(9.2.1节,包括get_scatter_slice_size、get_scatter_slice_ptr,还有 get_scatter_slice_size_member_ptr)抽象了iovec和WSABUF的特征,如清单31.3所示。

清单31.3. iovec 和 WSABUF 结构的属性垫片

Code View: Scroll / Show All
#if defined(PLATFORMSTL_OS_IS_UNIX)
inline void* const get_scatter_slice_ptr(struct iovec const& ss)
{
return ss.iov_base;
}
inline void*& get_scatter_slice_ptr(struct iovec& ss);
inline size_t get_scatter_slice_size(struct iovec const& ss)
{
return static_cast<size_t>(ss.iov_len);
}
inline size_t& get_scatter_slice_size(struct iovec& ss);
inline size_t iovec::*
get_scatter_slice_size_member_ptr(struct iovec const*)
{
return &iovec::iov_len;
}
#elif defined(PLATFORMSTL_OS_IS_WIN32)
inline void const* get_scatter_slice_ptr(WSABUF const& ss)
{
return ss.buf;
}
inline void*& get_scatter_slice_ptr(WSABUF& ss);
inline size_t get_scatter_slice_size(WSABUF const& ss)
{
return static_cast<size_t>(ss.len);
}
inline size_t& get_scatter_slice_size(WSABUF& ss);
inline u_long WSABUF::* get_scatter_slice_size_member_ptr(WSABUF const*)
{
return &WSABUF::len;
}
#endif /* operating system */

目前scatter_slice_sequence在UNIX上支持readv()/writev(),在Windows上支持WSARecv()/WSASend()和WSARecvFrom()/WSASendTo()。清单31.4展示了一个例子,首先用iovec特化scatter_slice_sequence,然后从一个文件描述符把内容读取到几个缓冲区中,经过STL方式的处理后,最终把转换后的结果写入到另外一个文件描述符。

清单31.4. 搭配 readv()和 writev()使用scatter_slice_sequence的例子

Code View: Scroll / Show All
int fs  = . . . // Opened for read
int fd  = . . . // Opened for write
for(;;)
{
const size_t  BUFF_SIZE = 100;
const size_t  MAX_BUFFS = 10;
char          buffers[MAX_BUFFS][BUFF_SIZE];
const size_t  numBuffers  = rand() % MAX_BUFFS;

// Declare an instance with arity of numBuffers
platformstl::scatter_slice_sequence<iovec>  sss(numBuffers);
  // Set up each slice in the sequence, which may be of
// different sizes in reality
{ for(size_t i = 0; i < numBuffers; ++i)
{
sss.set_slice(i, &buffers[i][0], sizeof(buffers[i]));
}}
if(0 != numBuffers) // In real scenario, might get 0 buffers
{
size_t  n = sss.read(::readv, fs); // Read from fs using ::readv()
if(0 == n)
{
break;
}
// "Process" the contents
std::transform( sss.payload().begin(), sss.payload().begin() + n
, sss.payload().begin(), ::toupper);
sss.write(::writev, fd, n); // Write n to fd using ::writev()
}
}

很显然这是一个非常简化的例子,不过我相信你能这样想象:fd和fs是socket描述符,缓冲区来自共享的内存区域(某个时刻可能没有富余空间),而“处理”也不一定像在(重新)传输前把内容改为大写这么简单。

序列的载荷(从payload()得到)提供了迭代器,用以随机访问内存块的内容。但我们必须认识到,这些迭代器就像std::deque一样是不连续的(2.3.6节)!对它们施加的指针算术运算只需常数时间,但区间遍历却不是线性时间操作。scatter_slice_sequence还没有完成,在正式发布到PlatformSTL子项目之前,其接口可能会进一步演化。(代码在CD上。)但它无疑提供了一组数据块表示为STL序列(2.2节)的能力,并提供适配器方法read()和write(),这些方法以文件/socket句柄和分散/聚集I/O函数为参数,然后将其应用到序列所持有的数据块。从逻辑上看,等价于通过“CreateLockBytesOnMemory()加上SYCLBOMF_FIXED_ARRAY和 CreateStreamOnLockBytes()”所创建的COM流对象。不过该适配器也存在一个明显的不足,即只能按照“一次一个元素”的方式遍历其内容,这有可能造成性能损失。(提示:这是以下有趣内容的一个线索…)

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

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇31.4.1. acestl::message_queue_s.. 下一篇31.4. 适配ACE_Message_Queue

评论

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