设为首页 加入收藏

TOP

31.5.2. acestl::message_queue_sequence, 版本2
2013-10-07 00:33:59 来源: 作者: 【 】 浏览:63
Tags:31.5.2. acestl::message_queue_sequence 版本

31.5.2. acestl::message_queue_sequence, 版本2

首先,我们需要知道何时可以进行块传输。ACE库基于char定义了不透明的内存块,也就是说指针的类型是char const*或者char*,大概是为了便于进行指针算术运算。这个策略我不敢苟同,但我的意见没什么用,ACE就是这么实现的。我们希望能够采用整块的方式,在char const*或char*类型的STL迭代器和acestl::message_queue_sequence::iterator之间传递内容。换句话说,以下代码应当调用两次memcpy(),而不是120次shared_handle::advance():

ACE_Message_Queue<ACE_NULL_SYNCH>   mq; // 2 message blocks, 120 bytes
char                                results[120];
acestl::message_queue_sequence<ACE_NULL_SYNCH>  mqs(mq);

std::copy(mqs.begin(), mqs.end(), &results[120]);

从连续内存拷贝数据到消息队列时,我们也希望获得同样的效率,如下:

std::copy(&results[0], &results[0] + STLSOFT_NUM_ELEMENTS(results)
, mqs.begin());

首要的事情是为message_queue_sequence定义块拷贝操作。清单31.10展示了该序列类新增的静态方法,fast_copy()重载。

清单 31.10. 定义message_queue_sequence 的算法辅助方法

Code View: Scroll / Show All
template <ACE_SYNCH_DECL>
class message_queue_sequence
{
. . .
static char* fast_copy(iterator from, iterator to, char* o)
{
#if defined(ACESTL_MQS_NO_FAST_COPY_TO)
for(; from != to; ++from, ++o)
{
*o = *from;
}
#else /* ACESTL_MQS_NO_FAST_COPY_TO */
from.fast_copy(to, o);
#endif /* ACESTL_MQS_NO_FAST_COPY_TO */
return o;
}
static iterator fast_copy(char const* from, char const* to
, iterator o)
{
#if defined(ACESTL_MQS_NO_FAST_COPY_FROM)
for(;from != to; ++from, ++o)
{
*o = *from;
}
#else /* ACESTL_MQS_NO_FAST_COPY_FROM */
o.fast_copy(from, to);
#endif /* ACESTL_MQS_NO_FAST_COPY_FROM */
return o;
}
. . .

我故意留下了禁止块操作的#define语句,只是为了在代码中说明另一种,也就是缺省的行为是什么。这些#define还有一个作用,就是允许方便地在块拷贝打开和关闭的情况下进行测试。(我们即将进行性能测试,有人闻出味儿了吗?)块拷贝模式下的代码使用了新的iterator::fast_copy()方法,这些新方法如清单31.11所示。

清单 31.11. iterator 的算法辅助方法的定义

class message_queue_sequence<. . .>::iterator
{
. . .
void fast_copy(char const* from, char const* to)
{
if(from != to)
{
ACESTL_ASSERT(NULL != m_handle);
m_handle->fast_copy(from, to, static_cast<size_type>(to - from));
}
}
void fast_copy(class_type const& to, char* o)
{
if(*this != to)
{
ACESTL_ASSERT(NULL != m_handle);
m_handle->fast_copy(to.m_handle, o);
}
}

真是急人,上面的方法还是什么都没有做,基本上就只是调用了shared_handle类新定义的同名方法,如清单31.12所示。shared_handle类的方法计算出每个块需要读/写的部分,然后调用memcpy()进行传输。

清单 31.12. shared_handle的算法辅助方法的定义

Code View: Scroll / Show All
struct message_queue_sequence<. . .>::iterator::shared_handle
{
. . .
void fast_copy(char const* from, char const* to, size_type n)
{
ACESTL_ASSERT(0 != n);
ACESTL_ASSERT(from != to);
if(0 != n)
{
size_type n1 = m_entryLength - m_entryIndex;
if(n <= n1)
{
::memcpy(&m_entryIndex[m_entry->rd_ptr()], from, n);
}
else
{
::memcpy(&m_entryIndex[m_entry->rd_ptr()], from, n1);
from += n1;
m_entry = nextEntry();
ACESTL_ASSERT(NULL != m_entry);
fast_copy(from, to, n - n1);
}
}
}
void fast_copy(class_type const* to, char* o)
{
size_type n1 = m_entryLength - m_entryIndex;
if( NULL != to &&
m_entry == to ->m_entry)
{
::memcpy(o, &m_entryIndex[m_entry->rd_ptr()], n1);
}
else
{
::memcpy(o, &m_entryIndex[m_entry->rd_ptr()], n1);
o += n1;
m_entry = nextEntry();
if(NULL != m_entry)
{
fast_copy(to, o);
}
}
}
. . .

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

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Visual C++从入门到精通 前言 下一篇31.4.2. acestl::message_queue_s..

评论

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