ACE 任务ACE_Task间通信


如前面所提到的,ACE 中的每个任务都有一个底层消息队列(参见上面的图示)。这个消息队列被用
作任务间通信的一种方法。当一个任务想要与另一任务“谈话”时,它创建一个消息,并将此消息放入
它想要与之谈话的任务的消息队列。接收任务通常用 getq()从消息队列里获取消息。如果队列中没有数据
可用,它就进入休眠状态。如果有其他任务将消息插入它的队列,它就会苏醒过来,从队列中拾取数据
并处理它。因而,在这种情况下,接收任务将从发送任务那里接收消息,并以应用特定的方式作出反馈。
下一个例子演示两个任务怎样使用它们的底层消息队列进行通信。这个例子包含了经典的生产者-
消费者问题的实现。生产者任务生成数据,将它发送给消费者任务。消费者任务随后消费这个数据。使
用 ACE_Task 构造,我们可将生产者和消费者看作是不同的 ACE_Task 类型的对象。这两种任务使用底层
消息队列进行通信。
 #include "ace/OS.h"
#include "ace/Task.h"
#include "ace/Message_Block.h"
 
//The Consumer Task.
class Consumer:
public ACE_Task<ACE_MT_SYNCH>
{
public:
int open(void*)
{
ACE_DEBUG((LM_DEBUG, "(%t) Producer task opened /n"));
 
//Activate the Task
activate(THR_NEW_LWP,1);
 
return 0;
}
 
//The Service Processing routine
int svc(void)
{
//Get ready to receive message from Producer
ACE_Message_Block * mb =0;
do
{
mb=0;
 
//Get message from underlying queue
getq(mb);
ACE_DEBUG((LM_DEBUG,
"(%t)Got message: %d from remote task/n",*mb->rd_ptr()));
}while(*mb->rd_ptr()<10);
 
return 0;
}
 
int close(u_long)
{
ACE_DEBUG((LM_DEBUG,"Consumer closes down /n"));
return 0;
}
};
 
class Producer:
public ACE_Task<ACE_MT_SYNCH>
{
public:
Producer(Consumer * consumer):
consumer_(consumer), data_(0)
{
mb_=new ACE_Message_Block((char*)&data_,sizeof(data_));
}
 
int open(void*)
{
ACE_DEBUG((LM_DEBUG, "(%t) Producer task opened /n"));
 
//Activate the Task
activate(THR_NEW_LWP,1);
return 0;
}
 
//The Service Processing routine
int svc(void)
{
while(data_<11)
{
//Send message to consumer
ACE_DEBUG((LM_DEBUG,
"(%t)Sending message: %d to remote task/n",data_));
consumer_->putq(mb_);
 
//Go to sleep for a sec.
ACE_OS::sleep(1);
data_++;
}
 
return 0;
}
 
int close(u_long)
{
ACE_DEBUG((LM_DEBUG,"Producer closes down /n"));
return 0;
}
 
private:
char data_;
Consumer * consumer_;
ACE_Message_Block * mb_;

};
 
int main(int argc, char * argv[])
{
Consumer *consumer = new Consumer;
Producer * producer = new Producer(consumer);
 
producer->open(0);
consumer->open(0);
 
//Wait for all the tasks to exit. ACE_Thread_Manager::instance()->wait();
}
 在此例中,生产者和消费者任务非常相似。它们都没有任何服务初始化或是终止代码。但两个类的
svc()方法是不同的。生产者在 open()方法中被启用后,svc()方法会被调用。在此方法中,生产者生成一
个消息,将它插入消费者的队列。消息是使用 ACE_Message_Block 类来生成的(要更多地了解如何使用
ACE_Message_Block,请阅读此教程及在线 ACE 指南中有关消息队列的章节)。生产者维护指向消费者
任务(对象)的指针。它通过该指针来将消息放入消费者的消息队列中。该指针在 main()函数中通过生
产者的构造器设置。
消费者驻留在它的 svc()方法的循环中,等待数据到达它的消息队列。如果队列中没有数据,消费者
就会阻塞并休眠(这是由 ACE_Task 类魔术般地自动完成的)。一旦数据到达消费者的队列,它就会苏醒
并消费此数据。
在此例中,生产者发送的数据由一个整数组成。生产者每次将这个整数加一,然后发送给消费者。
如你所看到的,生产者-消费者问题的解决方案十分简单,并且是面向对象的。在编写面向对象的
多线程程序时,使用 ACE_Task 是比使用低级线程 API 更好的方法。











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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值