ACE_Message_Block类 使用小结
来源:互联网 发布:淘宝丝塔芙旗舰店 编辑:程序博客网 时间:2024/06/05 19:07
ACE_Message_Block中有多个获取大小或者长度的函数,容易混淆.下图是根据ACE_Message_Block(实际是ACE_Da
红色表示是ACE_Message_Block独有的函数, 其余则ACE_Message_Block和ACE_Da
矩形纸上函数的返回值均为指针类型,之下的返回值均为size_t类型.
函数 说明
length() 有效数据的长度== wr_ptr() – rd_ptr()
size() 全部可用空间的长度,如果没有size()而变小,则等同capacity()== mark() – base()
space() 剩余可用空间的长度<= size() - length(),因为不含rd_ptr()移动过的空间== mark() – wr_ptr()
capacity() 最大空间的长度(ACE_Message_Block构造或初始化时所用参数值)== end() – base()
total_length() 复合消息(ACE_Message_Block内单向链 cont())的总长度
total_size() 复合消息(ACE_Message_Block内单向链 cont())的总大小
total_capacity() 复合消息(ACE_Message_Block内单向链 cont())的总空间大小
duplicate()浅拷贝函数,公用一个内部的ACE_Da
ACE_Message_Block::duplicate() 与 ACE_Da
ACE_Da
ACE_Message_Block:duplicate()则将自身copy了一份, 然后将自身的状态值赋给拷贝,注意它们公用同一个da
ACE_Message_Block::clone()深拷贝, 不但拷贝自身,内部的ACE_Da
ACE_Da
ACE_Message_Block.size(size_t len)函数是ACE_Da
如果len比现有的尺寸小, 简单的cur_size_ = length;
如果len比现有的尺寸大, 会申请新的空间并拷贝原所有数据.
注意! 这里可能会发生空间控制权的转换! 即标志位DONT_DELETE的变化.若原ACE_Da
对ACE_Message_Block和ACE_Da
ACE_Message_Block::crunch() 将现有数据移动到现有的缓冲的开始.
ACE_Message_Block::reset()将现有读写指针赋为初始值(ACE_Da
ACE_Message_Block::base()是对ACE_Da
1)ACE_Message_Block的构造函数中,如果da
所以需要特别注意, 在ACE_Message_Block的实例没有销毁之前,不能释放da
2)虽然ACE_Message_Block会根据size的值来更改自己的size(),但wr_ptr不会根据da
需要特别注意, 当构造一个ACE_Message_Block实例后, 随之需要追加数据时,必须设置wr_ptr的值,否则原有数据将会被覆写.
此时的含义是: ACE_Message_Block代管了da
默认定义的flag: enum { DONT_DELETE = 01, USER_FLAGS = 0x1000 }
1) set_flags()、clr_flags()是对ACE_Message_Block中的数据指针(ACE_Da
2) set_self_flags(),clr_self_flags()是对ACE_Message_Block本身进行设置.
ACE_Message_Block::copy(const char* buf) 函数将字符串copy到ACE_Message_Block, 如果内在空间不足, 将会返回-1.
需要特别注意, copy的数据将包括末尾的0, 也就是copy的数据长度为strlen(buf)+1.
而且, 会自动进行wr_ptr()的设置
ACE_Da
ACE_Da
注意, ACE_Da
ACE_Da
release()-> release_no_delete()->release_i()->~ACE_Da
如果在Stack上构造ACE_Da
如果在stack上构造ACE_Da
如果在heap上构造ACE_Da
ACE_Message_Block的用法
ACE_Message_Block在Ace中用来表示消息的存放空间,可用做网络通信中的消息缓冲区,使用非常频繁,下面将在如下方简单的介绍一下ACE_Message_Block相关功能。
创建消息块
释放消息块
从消息块中读写数据
数据的拷贝
其它常用函数
1。创建消息块
创建消息块的方式比较灵活,常用的有以下几种方式 :
1。直接给消息块分配内存空间创建。
ACE_Message_Block *mb = new ACE_Message_Block (30);
2。共享底层数据块创建。
char buffer[100];
ACE_Message_Block *mb = new ACE_Message_Block (buffer,30);
这种方式共享底层的数据块,被创建的消息块并不拷贝该数据,也不假定自己拥有它的所有权。在消息块mb被销毁时,相关联的数据缓冲区da
3。通过duplicate()函数从已有的消息块中创建副本。
ACE_Message_Block *mb = new ACE_Message_Block (30);
ACE_Message_Block *mb2 = mb->duplicate();
这种方式下,mb2和mb共享同一数据空间,使用的是ACE_Message_Block的引用计数机制。它返回指向要被复制的消息块的指针,并在内部增加内部引用计数。
4。通过clone()函数从已有的消息块中复制。
ACE_Message_Block *mb = new ACE_Message_Block (30);
ACE_Message_Block *mb2 = mb->clone();
clone()方法实际地创建整个消息块的新副本,包括它的数据块和附加部分;也就是说,这是一次"深拷贝"。
2。释放消息块
一旦使用完消息块,程序员可以调用它的release()方法来释放它。
如果消息数据内存是由该消息块分配的,调用release()方法就也会释放此内存。
如果消息块是引用计数的,release()就会减少计数,直到到达0为止;之后消息块和与它相关联的数据块才从内存中被移除。
如果消息块是通过共享已分配的底层数据块创建的,底层数据块不会被释放。
无论消息块是哪种方式创建的,只要在使用完后及时调用release()函数,就能确保相应的内存能正确的释放。
3。从消息块中读写数据
ACE_Message_Block提供了两个指针函数以供程序员进行读写操作,rd_ptr()指向可读的数据块地址,wr_ptr()指向可写的数据块地址,默认情况下都执行数据块的首地址。下面的例子简单了演示它的使用方法。
#include "ace/Message_Queue.h"
#include "ace/OS.h"
int main(int argc, char *argv[])
{
ACE_Message_Block *mb = new ACE_Message_Block (30);
ACE_OS::sprintf(mb->wr_ptr(),"%s","hello");
ACE_OS::printf("%s\n",mb->rd_ptr ());
mb->release();
return 0;
}
注意:这两个指针所指向的位置并不会自动移动,在上面的例子中,函数执行完毕后,执行的位置仍然是最开始的0,而不是最新的可写位置5,程序员需要通过wr_ptr(5)函数手动移动写指针的位置。
4。数据的拷贝
一般的数据的拷贝可以通过函数来实现数据的拷贝,copy()还会保证wr_ptr()的更新,使其指向缓冲区的新末尾处。
下面的例子演示了copy()函数的用法。
mb->copy("hello");
mb->copy("123",4);
注意:由于c++是以'\0'作为字符串结束标志的,对于上面的例子,底层数据块中保存的是"hello\0123\0",而用ACE_OS::printf("%s\n",mb->rd_ptr ());打印出来的结果是"hello",使用copy函数进行字符串连接的时候需要注意。
5。其它常用函数
length() 返回当前的数据长度
next() 获取和设置下一个ACE_Message_Block的链接。(用来建立消息队列非常有用)
space() 获取剩余可用空间大小
size() 获取和设置数据存储空间大小。
ACE_Message_Block使用心得
1 copy() 不需要让写指针后移.
ACE_Message_Block* mb = new ACE_Message_Block(BUFSIZ);
mb->copy(buff); //buff先已经初始化
2 初始化mb后需要后移指针的情况
2.1
ACE_Message_Block* mb = new ACE_Message_Block(buff,len);
mb->wt_ptr(len); //len是buff的长度 len = strlen(buff) +1
// +1 表示后面的\0
2.2
ACE_Message_Block* mb = new ACE_Message_Block(BUFSIZ);
ACE_OS::sprintf(mb->wt_ptr(),buff);
mb->wt_ptr(len);
2.3
ACE_Message_Block* mb = new ACE_Message_Block(len,
ACE_Message_Block::MB_DA
mb2, //表示 mb->cont(mb2)
buff)
mb->wt_ptr(len);
3.让消息接成串cont()时,千万不要直接或接间的把它接成一个环
mb->cont(mb2);
mb2->cont(mb3); //ok
***mb3->cont(mb); //死定了
4.通知其它线程结束时,可以通过ACE_Message_Block::MB_STOP
ACE_Message_Block* lastMsg =ACE_Message_Block ,ACE_Message_Block::MB_STOP)
otherTask->putq(lastMsg);
otherTask在接收到的时候如下处理
int OtherTask::svc()
{
ACE_Message_Block* mb;
while(1)
{
getq(mb);
if(mb->get_tpye() == ACE_Message_Block::MB_STOP)
{
mb->release();
break; //退出这个永久限环)
}
else
{
handle_message(mb); //处理这条消息
}
return 0;
}
注意:用putq压入一个ACE_Message_Block到ACE_Message_Queue时,如果被putq的是指针blk,则不能轻易release这个指针。因为putq的仅是这个指针而非指针所指内存,release指针所指内存后ACE_Message_Queue将会出错;如果被putq的是指针blk的blk->clone(),则后面可以 blk->release()。
- ACE_Message_Block类 使用小结
- ACE_Message_Block类 使用小结
- ACE_Message_Block类 使用小结
- ACE_Message_Block类
- ACE_Message_Block类
- ACE_Message_Block的使用注意事项
- ACE_Message_Block 简单使用
- ACE_Message_Block
- ACE_Message_Block
- ACE_Message_Block
- ACE_Message_Block
- ACE_Message_Block
- ACE_Message_Block的一个使用误区
- ACE_OutputCDR,ACE_InputCDR,ACE_Message_Block使用2
- 使用ACE_Message_Block需要注意的问题
- ACE_CDR::mb_align(ACE_Message_Block * mb)使用问题
- ACE第三个练习:ACE_Message_Block类
- ACE_Message_Block - [ACE]
- ibatis执行SQL语句打印控制台的log4j.xml文件配置方法
- UITableView最上面tableHeaderView留空间的两种方法
- 在Maven项目中使用第三方jar包
- struts2学习笔记(8)-------struts2的ajax支持
- 一个iOS 框架介绍:MKNetworkKit
- ACE_Message_Block类 使用小结
- 关于java
- SequoiaDB 资料汇总
- jconsole 连接 eclipse启动项目
- Oracle SQL plus环境设置与使用
- 华国锋换个方式
- POJ 2983 Is the Information Reliable?(差分约束系统)
- 串口下载的原理
- 【Android开发经验】来,咱们自己写一个Android的IOC框架!