peakzhang 发表于 2008-4-29 10:30:05

ace_task 的 ACE_Message_Queue 管理

在ace_task 框架中,使用 put(ACE_MEssage_Block *,...) 把消息压入队列,
但是使用 getq(ACE_Message_Block *&,...) 取出消息,传入的是指针的指针,
在内部还是会分配内存,比如
ACE_Message_Block *pCurrentMessageBlock=0;
getq(pCurrentMessageBlock);
...
//do with pCurrentMessageBlock
delete pCurrentMessageBlock;
有困惑的是,是不是 ACE_Task::getq() 方法是不是在分配
pCurrentMessageBlock 消息的时候,还会把原来的ACE_Message_Queqe
里面的一条消息 erase 了,否则,这个队列里面的消息什么时候释放??

peakzhang 发表于 2008-4-29 10:30:13

看 ace_task 的源代码,发现是这样实现的,ACE_Message_Queue 头消息出列,出列的这个消息被传入的指针引用了,这个实现有点巧妙,但是不是很理解 *& 和 ** 这两个东西

template <ACE_SYNCH_DECL> int
ACE_Message_Queue<ACE_SYNCH_USE>::dequeue_head_i (ACE_Message_Block *&first_item)
{
if (this->head_ ==0)
    ACE_ERROR_RETURN ((LM_ERROR,
                     ACE_LIB_TEXT ("Attempting to dequeue from empty queue")),
                      -1);
ACE_TRACE ("ACE_Message_Queue<ACE_SYNCH_USE>::dequeue_head_i");
first_item = this->head_;
this->head_ = this->head_->next ();

if (this->head_ == 0)
    this->tail_ = 0;
else
    // The prev pointer of first message block must point to 0...
    this->head_->prev (0);

peakzhang 发表于 2008-4-29 10:30:21

我刚才查看了ACE里面实现的代码,说实话,我有些困惑你提的问题。。。不知道应该如何回答。
据我所知,ACE_Message_Block,是使用引用计数来进行内存管理的。我们把有效的消息指针推入队列进行处理,只要保证在处理的时候,这个指针不被释放就可以了。并非非得复制一次。还可以使用增加指针计数的方法来操作,duplicate。

peakzhang 发表于 2008-4-29 10:30:27

指针和引用如(*& 和 **) 是C++里面比较玄妙的东西。如果一个函数,采用了*&的参数,你可以传入一个指针,函数内部会修改你指针本身的内容。如果只是*的参数,你把外面的指针传入函数的时候,函数内部相当于又生成了一个指针,指向你原来指针的指向的地址。外面的指针本身是不会被修改的。

仔细体会和测试一下就知道了。

peakzhang 发表于 2008-4-29 10:30:35

first_item = this->head_; //赋值,

this->head_ = this->head_->next (); // 头 ACE_Message_Block 出列

难道不是这样的吗,和引用

peakzhang 发表于 2008-4-29 10:30:45

first_item是指针的引用。直接修改了外面的指针本身。

peakzhang 发表于 2008-4-29 10:30:52

这个的确和引用计数没啥关系,但是ACE_Message_Block本身,使用引用计数来管理。
所以,必须保证进入队列的消息块,不能在被处理之前删除-引用计数为0,立刻删除。
页: [1]
查看完整版本: ace_task 的 ACE_Message_Queue 管理