`
ribishuangba
  • 浏览: 285306 次
文章分类
社区版块
存档分类
最新评论

ACE线程管理

 
阅读更多

运用ACE_Thread_Manager类创建线程

创建线程需要要解决两个问题,一是调用线程函数,二是提供一个途径让线程能够访问到外部传递过来的参数。下面的代码演示了基本的用法:
#include <stdexcept>
#include "ace/ACE.h"
#include "ace/Log_Msg.h"
#include "ace/Thread_Manager.h"
#include <map>
#include <string>
#include <iostream>
using namespace std;

class ThreadArg {
public:

ThreadArg() {
}
private:
string arg0;
public:

void setArg0(string value) {
arg0 = value;
}

string getArg0() const {
return arg0;
}
};

class MyThread {
public:
static void* run_svc(void* arg) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) MyThread running/n")));
ThreadArg* pArg = static_cast<ThreadArg*> (arg);
cout << pArg->getArg0() << endl;
}
};

int ACE_TMAIN(int, ACE_TCHAR *[]) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Main Thread running/n")));
ThreadArg threadArg;
threadArg.setArg0("ok");
ACE_thread_t threadID;
if (ACE_Thread_Manager::instance()->spawn(MyThread::run_svc, static_cast<void*>(&threadArg),
THR_DETACHED | THR_SCOPE_SYSTEM, &threadID) == -1) {
throw std::runtime_error("can't create a new thread in SnapShotReqWiater::run method");
}
ACE_Thread_Manager::instance()->wait();
return 0;
}

使用ACE_Thread_Manager::spawn方法创建线程,第一个参数是线程的函数,第二个是一个对象指针,里面存放了参数,其他的参数请参考文档
http://www.dre.vanderbilt.edu/Doxygen/5.7.5/html/ace/a00676.html#a36262a470e556182f5d69c4de7cfeaa1
wait方法等待线程运行完毕后才会返回。

运用ACE_Task_Base类创建线程

前面一种方法不够面向对象,线程需要成为一个对象,并且参数可以通过设置属性的形式自然的进行。下面的例子来自于<<ACE Programmers Guide>>,略作修改:
#include "ace/Task.h"
#include <string>
#include <iostream>
using namespace std;

class MyThread : public ACE_Task_Base {
public:

virtual int svc(void) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Handler Thread running/n")));
cout<<arg0<<endl;
ACE_OS::sleep(4);
return 0;
}

void setArg0(string const& arg0) {
this->arg0 = arg0;
}

string getArg0() const {
return arg0;
}

private:
string arg0;
};

int ACE_TMAIN(int, ACE_TCHAR *[]) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Main Thread running/n")));

MyThread thread;
string arg="ok";
thread.setArg0(arg);
int result = thread.activate();
ACE_ASSERT(result == 0);

thread.wait();
return 0;
}

MyThread类可以添加一些属性,svc成员函数可以内部访问这些属性。activate内部的实现代码实际上用的还是 ACE_Thread_Manager::spawn_n方法。现在我们很清楚,通过继承ACE_Task_Base类来创建线程是更方便和优雅的。

ACE_Task


线程之间常常需要通信,ACE有一种机制叫做消息队列。要获得这种能力,我们只需要使用ACE_Task_Base的子类ACT_Task即可。上面的例 子代码进行了一些修改,MyThread类从ACE_Task<>模板类派生,并且内部有一个循环,每隔四秒钟就会检查一下有没有消息,如果 消息类型是ACE_Message_Block::MB_STOP,则结束线程。
#include "ace/Task_T.h"
#include <string>
#include <iostream>
using namespace std;

class MyThread : public ACE_Task<ACE_MT_SYNCH> {
public:

virtual int svc(void) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Handler Thread running/n")));
cout << arg0 << endl;
for (;;) {
ACE_OS::sleep(4);
ACE_Message_Block * pMsg;
ACE_Time_Value time(0, 100);
if (getq(pMsg, &time) != -1) {
if (pMsg->msg_type() == ACE_Message_Block::MB_STOP) {
pMsg->release();
msg_queue_->close();
ACE_Thread::exit(0);
}
}
}
return 0;
}

void setArg0(string const& arg0) {
this->arg0 = arg0;
}

string getArg0() const {
return arg0;
}

private:
string arg0;
};

int ACE_TMAIN(int, ACE_TCHAR *[]) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Main Thread running/n")));

MyThread thread;
string arg="ok";
thread.setArg0(arg);
int result = thread.activate();
ACE_ASSERT(result == 0);

ACE_Message_Block* pMessage=new ACE_Message_Block(1);
pMessage->msg_type(ACE_Message_Block::MB_STOP);
thread.putq(pMessage);

thread.wait();
return 0;
}

注意:
1)putq和getq的第二个参数都是代表超时的时间,缺省为一直等待。
2)ACE_Message_Block作为消息,一般在发送者处用new创建,在接受者处调用release()方法销毁
3)msg_queue_->close();是关闭消息队列,使得发送者无法再发送消息。
4)msg_queue_->is_full()可以查看消息队列是否已经满
5) msg_queue_->high_water_mark()返回消息队列可以容纳的最后一个消息的索引,默认从0开始计数。我的机器上是默认最大索引是16384,也就是可以存放16385个消息。
6) msg_queue_->high_water_mark(size_t size)可以让我们重新设置消息队列的最大索引。

关于ACE_Task的消息队列和Windows消息队列的比较,可以看这篇文章:http://blog.csdn.net/imjj/archive/2006/08/19/1097248.aspx
最后给一个比较复杂的消息队列的应用,利用ACE_OutputCDR类将对象序列化到ACE_Message_Block中,然后加入消息队列,另一个线程取出后,通过ACE_InputCDR类反序列化回对象。
/*
* File: main.cpp
* Author: chenshu
*
* Created on December 1, 2009, 7:21 PM
*/


#include "ace/Task_T.h"
#include <string>
#include <iostream>
using namespace std;
#include "ace/CDR_Stream.h"

class FileMessage {
public:
static const ACE_CDR::ULong createdFile=0;

public:
ACE_CString getFolderPath() const {
return folderPath_;
}

void setFolderPath(ACE_CString const& path) {
folderPath_ = path;
}

ACE_CString getFileName() const {
return fileName_;
}

void setFileName(ACE_CString const& name) {
fileName_ = name;
}

ACE_CDR::ULong getFileMessageType() const{
return messageType_;
}

void setFileMessageType(ACE_CDR::ULong type) {
messageType_ = type;
}

ACE_CDR::ULong getSize() const {
return sizeof(ACE_CDR::ULong)+fileName_.length()+1+
sizeof(ACE_CDR::ULong)+
sizeof(ACE_CDR::ULong)+folderPath_.length()+1;
}
private:
ACE_CString fileName_;
ACE_CDR::ULong messageType_;
ACE_CString folderPath_;
};

int operator<<(ACE_OutputCDR & cdr, FileMessage const& message) {
cdr<<message.getFileName();
cdr<<message.getFileMessageType();
cdr<<message.getFolderPath();
return cdr.good_bit();
}

int operator>>(ACE_InputCDR & cdr, FileMessage & message) {
ACE_CString name;
cdr>>name;
message.setFileName(name);
ACE_CDR::ULong type;
cdr >> type;
message.setFileMessageType(type);
ACE_CString folderPath;
cdr>>folderPath;
message.setFolderPath(folderPath);
return cdr.good_bit();
}

class MyThread : public ACE_Task<ACE_MT_SYNCH> {
public:

virtual int svc(void) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Handler Thread running/n")));
cout << arg0 << endl;
cout << "high_water_mark:" << msg_queue_->high_water_mark() << endl;
for (;;) {
ACE_OS::sleep(4);
ACE_Message_Block * pMsg;
ACE_Time_Value time(0, 100);
if (getq(pMsg, &time) != -1) {
if (pMsg->msg_type() == ACE_Message_Block::MB_STOP) {
pMsg->release();
msg_queue_->close();
ACE_Thread::exit(0);
} else if(ACE_Message_Block::MB_DATA) {
ACE_InputCDR inputCDR(pMsg);
FileMessage message;
inputCDR>>message;
}
}
}
return 0;
}

void setArg0(string const& arg0) {
this->arg0 = arg0;
}

string getArg0() const {
return arg0;
}

private:
string arg0;
};

int ACE_TMAIN(int, ACE_TCHAR *[]) {
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Main Thread running/n")));

MyThread thread;
string arg = "ok";
thread.setArg0(arg);
int result = thread.activate();
ACE_ASSERT(result == 0);

FileMessage message;
message.setFileMessageType(FileMessage::createdFile);
message.setFileName("chenshu");
message.setFolderPath("/home/chenshu");
ACE_OutputCDR outputCDR(message.getSize()+ACE_CDR::MAX_ALIGNMENT);
outputCDR<<message;
ACE_Message_Block* pMessage=const_cast<ACE_Message_Block*>(outputCDR.begin());
thread.putq(pMessage);

thread.wait();
return 0;
}






分享到:
评论

相关推荐

    ACE学习文档大全.rar

    ACE 入门,ACE中文文档,ACE_Task框架,ACE的框架及其核心,ACE反应器(Reactor)模式,ACE线程管理机制,ACE通用服务端框架,ACE通用客户端框架,ACE中TCP通信

    ACE-6.5.0.tar.bz2

    ACE线程,进程启动、管理的C++源码,windows/VS,linux可编译成动态库,实测好用.................

    ACE程序员指南.pdf

     线程管理  事件多路分离和处理器分派  连接建立和服务初始化  软件的静态和动态配置、重配置  分层协议构建和流式框架  分布式通信服务名字、日志、时间同步、事件路由和网络锁定等等。

    ACE入门教程

    ACE 入门教程 设置环境变量 ACE结构简介 线程的创建与管理 程序示例

    ACE网络编程指南介绍

    ACE(自适配通信环境:Adaptive Communication Environment),封装了OS层的底层API,并结合设计模式为各种操作平台...开发包的内容涉及到:进程间通信、内存管理、线程管理、同步、网络通信、事件分发、服务器配置等。

    这是一个c++进阶编程的文档

    这是一个c++进阶编程的文档,包含了实现stl容器,C++的内存管理,深度探索c++对象模型,ACE网络编程,UNIX网络编程,多线程编程,模板的扩展使用,c专家编程,C的缺陷和漏洞.zip这是一个c++进阶编程的文档,包含了...

    rar压缩软件.rar

    RAR 是一个让你在命令行模式中管理压缩文件的控制台应用。RAR 提供压缩、加 密、数据恢复和许多其它此手册中描述的其它功能。 RAR 只支持 RAR 格式压缩文件,它默认有 .rar 扩展名。不支持ZIP 和其他格 式。即使...

    彩虹云任务挂机系统

    强大的任务运行机制:分布式任务调度、秒刷模式、多线程模式,提升运行效率,并力求将服务器负载降到最低 完善的QQ管理系统:增加QQ账号管理,添加QQ任务更加快捷,一键更新失效的sid,sid失效邮件提醒。 丰富的QQ...

    java多线程tcpsocketserver源码-HackingTools:与众多黑客工具相关的链接

    java多线程tcp socket server源码黑客工具 Enlaces de interés con multitud de herramientas hacking。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32 0.7.1.1 小巧的免费代理...

    彩虹网络任务5.4 php源码

    强大的任务运行机制:分布式任务调度、秒刷模式、多线程模式,提升运行效率,并力求将服务器负载降到最低 完善的QQ管理系统:增加QQ账号管理,添加QQ任务更加快捷,一键更新失效的sid。 丰富的QQ挂机功能:拥有说说...

    【运营版】彩虹云7.27免授权版任务挂机平台/彩虹秒赞网平台PHP

    2.强大的任务运行机制:分布式任务调度、秒刷模式、多线程模式,提升运行效率,并力求将服务器负载降到最低。自定义运行时间,自定义使用代理,自定义代理ip及端口号,自定义POST模拟,自定义POST数据,自定义来源地址,...

    java多线程tcpsocketserver源码-awesome-lists-awesome-hacking-tools:真棒列表真棒黑客工具

    java多线程tcp socket server源码很棒的黑客工具 精选的令人敬畏的黑客工具列表。 如果您想为此列表做出贡献,请向我发送拉取请求。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32...

    Ashampoo Zip Pro v1.0.5.zip

    支持多核处理器,多线程处理 ZIP 和 7-ZIP 文件 方便的格式转换 一些压缩文件使用了不常用的格式,压缩率很低。可以将这些文件转换为更好的格式,如 7-ZIP! 读取和写入 ZIP-、ZIPX、7-Zip、LHA-、CAB-、TAR-/GZ-...

    Windows2000 服务器端应用程序开发设计指南

    WMI 08-05-01 Windows2000服务器端应用程序开发设计指南-信任成员的管理1 08-05-01 Windows2000服务器端应用程序开发设计指南-信任成员的管理2 08-05-01 Windows2000 服务器端应用程序开发设计指南-存取控制(1) 08-...

    好压解压缩软件

    2345好压(HaoZip)是强大的压缩文件管理器、一个免费的压缩软件。 1. 完整支持 7Z/ZIP/BZIP2/GZIP/XZ/LZH/WIM/TAR 文件的压缩与解压,并可以创建分卷压缩文件、自解压文件,同时支持对压缩文件的加密。 2. 支持...

    C++开源程序库 C++开源程序库

    1、系统和网络编程库:ACE 除了ACE之外,还有很多系统和网络编程方面的程序库。比如在线程库方面,还有ZThread、boost::thread,如果放大到C/C++领域,还有APR,还有CII。在文件和目录操作方面,boost也有相应的...

    Archivist NetDCA-开源

    档案管理员是一种网络设备配置档案程序,使用Subversion作为修订控制系统。 您可以使用Archivist备份和跟踪对网络中的路由器和交换机所做的配置更改。 由于多线程操作,归档师可以非常快。 在几分钟之内,您可以检查...

    informix 实用大全

    4.6 虚拟处理器与监视线程 4.7 用备份与日志保持容错 4.8 使用pdq与分块 4.9 更多信息 4.10 informix与其他参考资料 第5章 informix sql的独特特性 5.1 informix sql及其特性 5.2 遵循ansi sql标准 ...

    Gh0st RAT Beta 3.6 C++源码

    新加了备注功能. 2008/2/09 22:58 : 修正一些大家提到的问题,Gh0st RAT Beta 2.1 发布 2008/2/11 00:18 : 修正服务端安装的一个BUG,静心研究ACE中,暂停更新................... 2008/2/17 16:14 : 保存配置...

    Total Commander 9.12 1.4 增强版

    •支持与文件管理器和桌面之间的拖放操作。 •支持命令行:输入程序名、或按CTRL+ENTER、CTRL+SHIFT+ENTER即可,便于带参数启动程序。 •工具栏和开始菜单均可配置:将常用的DOS或Windows程序加入开始菜单中,运行...

Global site tag (gtag.js) - Google Analytics