ACE_Message_Queue

本文介绍了ACE框架中的消息队列ACE_Message_Queue,它不同于System V的消息队列模型,主要用于线程间通信。文章讲解了基于traits策略的类设计,如ACE_MT_SYNCH和ACE_NULL_SYNCH,以及消息块ACE_Message_Block的使用,包括数据缓存、引用计数和消息类型的设置。此外,还提供了一个简单的ACE_Message_Block使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.与System V的消息队列模型不同
 
ACE_Message_Queue的模型是仿照System V streams提供的排队设施设计的,但是与System V排队设施不同,使用ACE的排队设施,可以在单个进程中进行高效的线程间通信,但是没有提供用于进程间通信的排队设施。
 
 
2.基于traits策略的类的设计
 
为了实现线程安全,经常要实现多种版本的库,多线程库、单线程库,这样会给库的维护与开发带来很多问题,而在ACE中经常看到ACE_<ACE_XXX>这种用法,ACE_XXX类代表的是一系列的宏定义,这些宏决定了使用哪种策略。例如消息队列的使用要public ACE_Task<ACE_MT_SYNCH>而参数ACE_MT_SYNCH的定义如下:
class ACE_Export ACE_MT_SYNCH
{
public:
  typedef ACE_Thread_Mutex MUTEX;
  typedef ACE_Null_Mutex NULL_MUTEX;
  typedef ACE_Process_Mutex PROCESS_MUTEX;
  typedef ACE_Recursive_Thread_Mutex RECURSIVE_MUTEX;
  typedef ACE_RW_Thread_Mutex RW_MUTEX;
  typedef ACE_Condition_Thread_Mutex CONDITION;
  typedef ACE_Condition_Recursive_Thread_Mutex RECURSIVE_CONDITION;
  typedef ACE_Thread_Semaphore SEMAPHORE;
  typedef ACE_Null_Semaphore NULL_SEMAPHORE;
};
可以对比下另外一个参数ACE_NULL_SYNCH
class ACE_Export ACE_NULL_SYNCH
{
public:
  typedef ACE_Null_Mutex MUTEX;
  typedef ACE_Null_Mutex NULL_MUTEX;
  typedef ACE_Null_Mutex PROCESS_MUTEX;
  typedef ACE_Null_Mutex RECURSIVE_MUTEX;
  typedef ACE_Null_Mutex RW_MUTEX;
  typedef ACE_Null_Condition CONDITION;
  typedef ACE_Null_Condition RECURSIVE_CONDITION;
  typedef ACE_Null_Semaphore SEMAPHORE;
  typedef ACE_Null_Mutex NULL_SEMAPHORE;
};
简单比较下第一个宏MUTEX的定义,在MT_SYNCH(多线程同步)里面为ACE_Thread_Mutex 而在NULL_SYNCH(单线程同步)里面为ACE_Null_Mutex,而ACE_NULL_Mutex是一个“方法都没有实现的互斥锁”,ACE_NULL_Mutex与ACE_Thread_Mutex 有相同的接口,但是没有实现任何方法,所以使用起来接口一样,但效果不一样。这样就把一个类ACE_MT_SYNCH作为参数,从而决定了ACE_Task的消息队列的实现,从而简化了库的设计。ACE中大量这样的用法,依照具体的的类型产生相应的模板或者模板函数,通过模板参数实现根据环境需要改变其行为方式,通过静态绑定来进一步提高效率。这种策略叫做traits策略,与strategy有很大不同:traits 策略的替换是在编译时确定的,strategy是通过动态绑定实现的。


 
3.消息块ACE_Message_Block的使用
 
消息块是消息队列中的固定的对象结构,可以把消息块当成一种高级的数据缓存区,支持引用计数和数据共享,每个消息块都含有两个指针:rd_ptr()和指向要读取的下一个字节:wr_ptr()。一旦使用完了消息块,要用release()方法释放它,从而使引用计数减一,当计数到达0的时候,ACE会自动释放分配的内存。消息块还有一个类型字段,可以通过msg_type()修改设置,还提供了一个duplicate()方法,用以创建一个新的指向块的数据的引用,并使引用计数加一,另外还提供了clone()方法,用以创建消息块的深度拷贝。
/**
 * @class ACE_Message_Block
 *
 * @brief Stores messages for use throughout ACE (particularly
 * in an ACE_Message_Queue).
 *
 * An ACE_Message_Block is modeled after the message data
 * structures used in System V STREAMS.  Its purpose is to
 * enable efficient manipulation of arbitrarily large messages
 * without incurring much memory copying overhead.  Here are the
 * main characteristics of an ACE_Message_Block:
 * - Contains a pointer to a reference-counted
 *   ACE_Data_Block, which in turn points to the actual data
 *   buffer.  This allows very flexible and efficient sharing of
 *   data by multiple ACE_Message_Block objects.
 * - One or more ACE_Message_Blocks can be linked to form a
 *    ``fragment chain.''
 * - ACE_Message_Blocks can be linked together in a doubly linked fashion
 *   to form a queue of messages (this is how ACE_Message_Queue works).
 *
 * @see C++NPv1, section 4.2; APG, section 12.3.2.
 */
 
4.ACE_Message_Block Demo
[cpp] view plaincopy
// message_block.cpp  
  
#include "ace/Task.h"  
  
  
int ACE_TMAIN(int, ACE_TCHAR *[])  
{  
    //use copy   
    ACE_Message_Block *mb;  
    ACE_NEW_RETURN(mb, ACE_Message_Block(128), -1);  
  
    const char *deviceAddr = "Dev#12";  
    mb->copy(deviceAddr, ACE_OS::strlen(deviceAddr) + 1);  
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("Devide addr -->%s\n"), mb->rd_ptr()));  
  
    //use  wr_ptr()  
    ACE_Message_Block *mb2;  
    ACE_NEW_RETURN(mb2, ACE_Message_Block(128), -1);  
  
    const char *commandSeq = "commandSeq#14";  
    ACE_OS::sprintf(mb2->wr_ptr(), commandSeq);  
    //move the wr_ptr() forward in the buffer by the amount of data we put in.  
    mb2->wr_ptr(ACE_OS::strlen(commandSeq)+1);  
  
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("Command Sequence -->%s\n"), mb2->rd_ptr()));  
    //the rd_ptr() also need forward  
    mb2->rd_ptr(ACE_OS::strlen(mb2->rd_ptr())+1);  
    mb2->release();  
  
    //the use of msg_type()  
    //send a hangup notification to the receiver.  
    ACE_NEW_RETURN(mb2, ACE_Message_Block(128, ACE_Message_Block::MB_HANGUP), -1);  
    //send an error notification to the receiver.  
    mb2->msg_type(ACE_Message_Block::MB_ERROR);  
  
    return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值