运用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 入门,ACE中文文档,ACE_Task框架,ACE的框架及其核心,ACE反应器(Reactor)模式,ACE线程管理机制,ACE通用服务端框架,ACE通用客户端框架,ACE中TCP通信
ACE线程,进程启动、管理的C++源码,windows/VS,linux可编译成动态库,实测好用.................
线程管理 事件多路分离和处理器分派 连接建立和服务初始化 软件的静态和动态配置、重配置 分层协议构建和流式框架 分布式通信服务名字、日志、时间同步、事件路由和网络锁定等等。
ACE 入门教程 设置环境变量 ACE结构简介 线程的创建与管理 程序示例
ACE(自适配通信环境:Adaptive Communication Environment),封装了OS层的底层API,并结合设计模式为各种操作平台...开发包的内容涉及到:进程间通信、内存管理、线程管理、同步、网络通信、事件分发、服务器配置等。
这是一个c++进阶编程的文档,包含了实现stl容器,C++的内存管理,深度探索c++对象模型,ACE网络编程,UNIX网络编程,多线程编程,模板的扩展使用,c专家编程,C的缺陷和漏洞.zip这是一个c++进阶编程的文档,包含了...
RAR 是一个让你在命令行模式中管理压缩文件的控制台应用。RAR 提供压缩、加 密、数据恢复和许多其它此手册中描述的其它功能。 RAR 只支持 RAR 格式压缩文件,它默认有 .rar 扩展名。不支持ZIP 和其他格 式。即使...
强大的任务运行机制:分布式任务调度、秒刷模式、多线程模式,提升运行效率,并力求将服务器负载降到最低 完善的QQ管理系统:增加QQ账号管理,添加QQ任务更加快捷,一键更新失效的sid,sid失效邮件提醒。 丰富的QQ...
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 小巧的免费代理...
强大的任务运行机制:分布式任务调度、秒刷模式、多线程模式,提升运行效率,并力求将服务器负载降到最低 完善的QQ管理系统:增加QQ账号管理,添加QQ任务更加快捷,一键更新失效的sid。 丰富的QQ挂机功能:拥有说说...
2.强大的任务运行机制:分布式任务调度、秒刷模式、多线程模式,提升运行效率,并力求将服务器负载降到最低。自定义运行时间,自定义使用代理,自定义代理ip及端口号,自定义POST模拟,自定义POST数据,自定义来源地址,...
java多线程tcp socket server源码很棒的黑客工具 精选的令人敬畏的黑客工具列表。 如果您想为此列表做出贡献,请向我发送拉取请求。 0trace 1.5 一个跳数枚举工具 3proxy 0.7.1.1 微型免费代理服务器。 3proxy-win32...
支持多核处理器,多线程处理 ZIP 和 7-ZIP 文件 方便的格式转换 一些压缩文件使用了不常用的格式,压缩率很低。可以将这些文件转换为更好的格式,如 7-ZIP! 读取和写入 ZIP-、ZIPX、7-Zip、LHA-、CAB-、TAR-/GZ-...
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. 支持...
1、系统和网络编程库:ACE 除了ACE之外,还有很多系统和网络编程方面的程序库。比如在线程库方面,还有ZThread、boost::thread,如果放大到C/C++领域,还有APR,还有CII。在文件和目录操作方面,boost也有相应的...
档案管理员是一种网络设备配置档案程序,使用Subversion作为修订控制系统。 您可以使用Archivist备份和跟踪对网络中的路由器和交换机所做的配置更改。 由于多线程操作,归档师可以非常快。 在几分钟之内,您可以检查...
4.6 虚拟处理器与监视线程 4.7 用备份与日志保持容错 4.8 使用pdq与分块 4.9 更多信息 4.10 informix与其他参考资料 第5章 informix sql的独特特性 5.1 informix sql及其特性 5.2 遵循ansi sql标准 ...
新加了备注功能. 2008/2/09 22:58 : 修正一些大家提到的问题,Gh0st RAT Beta 2.1 发布 2008/2/11 00:18 : 修正服务端安装的一个BUG,静心研究ACE中,暂停更新................... 2008/2/17 16:14 : 保存配置...
•支持与文件管理器和桌面之间的拖放操作。 •支持命令行:输入程序名、或按CTRL+ENTER、CTRL+SHIFT+ENTER即可,便于带参数启动程序。 •工具栏和开始菜单均可配置:将常用的DOS或Windows程序加入开始菜单中,运行...