面向对象的线程类ACE_Task

面向对象的线程类ACE_Task

 

我们在前一章中使用ACE_Thread包装时,你一定已经注意到了一些不够"优雅"的地方。那一章中的大多数程序都被分解为函数、而不是对象。这是因为ACE_Thread包装需要一个全局函数名、或是静态方法作为参数。随后该函数(静态方法)就被用作所派生的线程的"启动点"。这自然就使得程序员要为每个线程写一个函数。如我们已经看到的,这可能会导致非面向对象的程序分解。

ACE_Task对常用线程处理进行了OO包装,通过ACE_Task,能对线程进行更好的操作。

ACE_TaskACE中的任务或主动对象处理结构的基类。ACE使用此类来实现主动对象模式。所有希望成为主动对象的对象都必须由此类派生。同时可将它看作是更高级的、更为面向对象的线程。

每个任务都含有一或多个线程,以及一个底层消息队列。各个任务通过消息队列进行通信。至于消息队列实现的内在细节程序员不必关注。发送任务用putq() 将消息插入到另一任务的消息队列中,接收任务通过使用getq()将消息提取出来。这样的体系结构大大简化了多线程程序的编程模型。

其主要成员如下:

open():初始化资源

close():释放资源

activate():启动线程,可指定线程的数目

svc():线程的启动位置

     putq():放置消息到任务的消息队列中

     getq():从任务的消息队列中取出消息

     thr_count():返回任务中线程的数目

     last_thread():返回任务中将线程计数器从1降为0的线程的ID

 

要创建任务,需要进行以下步骤:

1.    实现服务初始化和终止方法:
open()
方法应该包含所有专属于任务的初始化代码。其中可能包括诸如连接控制块、锁和内存这样的资源。close()方法是相应的终止方法。

2.    调用启用(Activation)方法:
在主动对象实例化后,你必须通过调用activate()启用它。要在主动对象中创建的线程的数目,以及其他一些参数,被传递给activate()方法。activate()方法会使svc()方法成为所有它生成的线程的启动点。

3.    实现服务专有的处理方法:
如上面所提到的,在主动对象被启用后,各个新线程在svc()方法中启动。应用开发者必须在子类中定义此方法。

下面的例子演示怎样去创建任务:

#include "ace/Task.h"
#include "ace/OS.h"
#include<iostream>
usingnamespace std;
class TaskThread: public ACE_Task<ACE_MT_SYNCH>
{
public:
virtualint svc(void)
 {
for(int i=0;i<10;i++)
 {
 ACE_OS::sleep(1);
 cout<<endl<<"hello thread1"<<endl;
 }
return 0;
 }
};
int main(int argc, char *argv[])
{
 TaskThread task;
 task.activate();
while(true)
 ACE_OS::sleep(10);
return 0;
}


ACE_Task也封装了常用线程操作,如暂停,恢复及停止等,是不是非常简单和方便呢。

其实ACE_Task的使用还不仅仅是这些,通过它还可实现一种很常用的网络编程模式--主动对象模式,其具体功能在后续的设计模式部分将作详细的介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值