文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>ACE_Message_Block类 使用小结(三)

ACE_Message_Block类 使用小结(三)

时间:2010-10-24  来源:ronat

ACE_Message_Block的用法

 

ACE_Message_Block在Ace中用来表示消息的存放空间,可用做网络通信中的消息缓冲区,使用非常频繁,
下面将在如下方简单的介绍一下ACE_Message_Block相关功能。

 

创建消息块
释放消息块
从消息块中读写数据
数据的拷贝
其它常用函数

 

1.   创建消息块

 

创建消息块的方式比较灵活,常用的有以下几种方式 :

 

l  直接给消息块分配内存空间创建。

    

ACE_Message_Block *mb = new ACE_Message_Block (30);

l  共享底层数据块创建。

   

char buffer[100];
ACE_Message_Block *mb = new ACE_Message_Block (buffer,30);

 

这种方式共享底层的数据块,被创建的消息块并不拷贝该数据,也不假定自己拥有它的所有权。在消息块mb被销毁时,
相关联的数据缓冲区data将不会被销毁。这是有意义的:消息块没有拷贝数据,因此内存也不是它分配的,这样它也不应该负责销毁它。

 

l  通过duplicate()函数从已有的消息块中创建副本。

    

ACE_Message_Block *mb = new ACE_Message_Block (30);
ACE_Message_Block *mb2 = mb->duplicate();

 

这种方式下,mb2和mb共享同一数据空间,使用的是ACE_Message_Block的引用计数机制。
它返回指向要被复制的消息块的指针,并在内部增加内部引用计数。

 

l  通过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);


 

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_DATA,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;

}

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载