ace使用之消息队列

概览:

    


详解:

通过cpp network programming volume2 中的该图可以简单看出ACE_Message_Queue, ACE_Message_Block, 以及ACE_Data_Block的关系;下面主要讲解使用这些类的过程中需要注意的问题,

实例:(windows+vs2010)

  

#include "stdafx.h"
#include "ace/Message_Block.h"
#include "ace/Thread_Mutex.h"
#include "ace/Lock_Adapter_T.h"
#include "ace/Condition_Thread_Mutex.h"

#include "ace/Message_Queue_T.h"
#include "ace/Synch_Traits.h"

#include <stdio.h>
#pragma comment(lib, "ACEd.lib")

//message_block default allocator ACE_New_Allocator.

#define MESSAGE_DEFAULT_BUFFER_SIZE	1024

int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
	ACE_Thread_Mutex *pThreadMutex;
	ACE_NEW_RETURN(pThreadMutex, ACE_Thread_Mutex, -1);
	if( pThreadMutex == (void *)-1 )
	{
		fprintf(stderr, "pThreadMutex allocation failed.\n" );
	}
	ACE_Lock_Adapter<ACE_Thread_Mutex> lock(*pThreadMutex);

	ACE_Message_Block *pmb = ::new ACE_Message_Block(
		MESSAGE_DEFAULT_BUFFER_SIZE,
		ACE_Message_Block::MB_DATA,
		0,
		0,
		0,
		&lock);

	pmb->copy("I am testing, I am testing, I am testing, I am testing, I am testing, I am testing, I am testing");


	ACE_Message_Block *pmb1 = ::new ACE_Message_Block(MESSAGE_DEFAULT_BUFFER_SIZE);

	pmb1->copy("i am mb1, i am mb1, i am mb1, i am mb1, i am mb1, i am mb1, i am mb1, i am mb1, i am mb1");

	ACE_Message_Block *pmb2 = ::new ACE_Message_Block(MESSAGE_DEFAULT_BUFFER_SIZE);

	pmb2->copy("i am mb2, i am mb2,i am mb2,i am mb2,i am mb2,i am mb2,i am mb2,i am mb2,i am mb2,i am mb2");


	ACE_Message_Queue<ACE_MT_SYNCH> mq;
	mq.enqueue( pmb);
	mq.enqueue( pmb1);
	mq.enqueue( pmb2 );

	ACE_Message_Queue_Iterator<ACE_MT_SYNCH> mqIter(mq);

	ACE_Message_Block *pBlock = NULL;
	for( ; mqIter.next(pBlock) ;  mqIter.advance() )
	{
		fprintf(stdout, "%s\n", pBlock->rd_ptr() );
	}

	//delete pThreadMutex;

	getchar();
	return 0;
}
@注意事项:

@1 在使用ACE_Messag_Block定义的对象指针必须能够被delete,无论该内存是通过堆或者栈分配出来再构造亦或直接new分配构造。

@2 上述实例中的pThreadMutex一定不能被提前delete掉,因为在ACE_Message_Queue在析构时,会调用内部所有的ACE_Message_Block的release方法,代码:

template <ACE_SYNCH_DECL> int
ACE_Message_Queue<ACE_SYNCH_USE>::flush_i (void)
{
  int number_flushed = 0;

  // Remove all the <ACE_Message_Block>s in the <ACE_Message_Queue>
  // and <release> their memory.
  for (this->tail_ = 0; this->head_ != 0; )
    {
      ++number_flushed;

      size_t mb_bytes = 0;
      size_t mb_length = 0;
      this->head_->total_size_and_length (mb_bytes,
                                          mb_length);
      // Subtract off all of the bytes associated with this message.
      this->cur_bytes_ -= mb_bytes;
      this->cur_length_ -= mb_length;
      --this->cur_count_;

      ACE_Message_Block *temp = this->head_;
      this->head_ = this->head_->next ();

      // Make sure to use <release> rather than <delete> since this is
      // reference counted.
      temp->release ();
    }

#if defined (ACE_HAS_MONITOR_POINTS) && (ACE_HAS_MONITOR_POINTS == 1)
  // The monitor should output only if the size has actually changed.
  if (number_flushed > 0)
    {
      this->monitor_->receive (this->cur_length_);
    }
#endif

  return number_flushed;
}

而release方法中使用了出入的ACE_Lock对象指针,代码如下:

// Grab the lock that belongs to my data block
      lock = this->data_block ()->locking_strategy ();

      // if we have a lock
      if (lock != 0)
        {
          // One guard for all
          ACE_GUARD_RETURN (ACE_Lock, ace_mon, *lock, 0);

          // Call non-guarded release with @a lock
          destroy_dblock = this->release_i (lock);
        }

所以要想掌握析构的顺序,最好将ACE_Message_Queue也能支持delete操作符。

@3 ACE_Message_Block中内聚了ACE_Data_Block对象指针,ACE_Data_Block中内存的分配默认使用ACE_New_Allocator。ACE中的Allocators种类有:

所以自己也可以定义Allocator作为ACE_Message_Block的参数传入。

@4 在ACE_Message_Queue中有三个参数,前两个代表高水位和低水位,高水位主要是指enqueue的ACE_Message_Block的最大字节数总和,低水位代表在dequeue时,如果发现自己数低于低水位,那么通知等待enqueue的线程可以继续了。

@5 ACE也提供了ACE_Message_Queue_Ex供我们选择队列中存放的类型,

template <class ACE_MESSAGE_TYPE, ACE_SYNCH_DECL>
class ACE_Message_Queue_Ex

转载于:https://my.oschina.net/shawnChen/blog/102719

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值