为什么要使用ACE_Task来管理线程
从C#转到C++后,感觉到C++比C#最难的地方,就是在系统编程时,C#中有对应的类库,我接触到一个类后,就可以通过这个类,知道很多相关的功能。而在C++中,必须使用Windows API,但是Windows API的缺点反而是不系统。比如,想要创建一个线程时,C#中可以通过新建一个Thread类,我得到这个类后,就可以通过帮助或者MSDN了解到这个类中有哪些方法,如何管理线程等。但是C++中,创建一个线程,需要调用CreateThread,但因为它是一个API,所以很难快速的了解到与线程管理相关的API,至少对我来说,这是一个难点。
C#的优势是以类的方式去管理线程,而C++ 调用API更像是在单打独斗,显得特别特别散乱。
那么在C++中,我们能不能以类的方式去管理线程呢。针对这个问题,ACE_Task便浮出了水面。
ACE_Task使用方法
ACE_Task对常用线程处理进行了OO包装,通过ACE_Task,能对线程进行更好的操作。
根据ACE_Task的父类ACE_Task_Base中的注释,可以总结出以下几点:
- 想要使用ACE_Task,就要从ACE_Task派生一个子类,然后实现比较重要的几个虚方法。
- 实现服务初始化和终止方法:open()方法应该包含所有专属于任务的初始化代码。其中可能包括诸如连接控制块、锁和内存这样的资源。close() 方法是相应的终止方法。
- 调用启用(Activation )方法:在主动对象实例化后,你必须通过调用activate()启用它。要在主动对象中创建的线程的数目,以及其他一些参数,被传递给activate()方法。activate()方法会使svc()方法成为所有它生成的线程的启动点。
- 实现服务专有的处理方法:如上面所提到的,在主动对象被启用后,各个新线程在svc()方法中启动。应用开发者必须在子类中定义此方法。
编写ACE_Task的Demo
下面就通过总结的几点来编写一个Demo
首先是派生ACE_Task的子类ShowTask
#pragma once
#include "ace/Task_T.h"
#include <string>
#include <iostream>
using namespace std; class ShowTask : public ACE_Task<ACE_SYNCH>
{
public:
ShowTask(const char* str_to_show, int interval) : show_str_(str_to_show), interval_(interval)
{
//启动线程
activate();
}
~ShowTask()
{
//结束线程
close();
}
public:
virtual int open( void *args = 0 )
{
cout << "线程启动" << endl;
return 0;
} virtual int close( u_long flags = 0 )
{
cout << "线程结束" << endl;
return 0;
} virtual int svc( void )
{
int time_begin = GetTickCount();
while(true)
{
int time_end = GetTickCount();
if(time_end - time_begin >= interval_)
{
time_begin = time_end;
cout << show_str_ << endl;
}
Sleep(10);
}
return 0;
}
private:
//需要显示的信息
string show_str_;
//间隔多长时间进行显示
int interval_;
};
然后在程序中调用ShowTask
#include "ShowTask.h" int _tmain(int argc, _TCHAR* argv[])
{
ACE::init();
string str = "这是一个测试程序";
ShowTask task(str.c_str(), 1000); Sleep(10000);
ACE::fini();
return 0;
}
运行效果图:
需要注意的地方
在程序中使用ACE_Task,那么就必须在使用前对ACE进行初始化,即调用ACE::init方法,然后在程序结束的时候调用ACE::fini方法。如果没有进行初始化就调用ShowTask,那么程序就会崩溃。
至于为什么会崩溃,以及ACE::init方法做了些什么,后续的文章中会详细的介绍。
关于open方法的疑惑
从上面的测试图中可以看到,线程结束后,调用了close方法,但是在线程启动时并没有调用open方法。
而且从谷歌找到的资料中也介绍,在线程启动的时候回调用open方法,而且他们的示例程序与本文中提供的demo中关于ACE_Task的使用方法也基本一致。
那么open方法为什么没有被调用呢,究竟是使用方法不对,还是因为ACE版本不同导致的。关于这个问题也会在后续的文章中进行详细的介绍。
使用ACE_Task管理线程的更多相关文章
-
使用Executor管理线程
上一篇博客(第一个并发程序:定义任务和驱动任务)中,我们使用Thread对象启动线程,而java.util.concurrent包的Executor执行器提供了更好的管理Thread对象的方法,从而简 ...
-
java笔记--用ThreadLocal管理线程,Callable<;V>;接口实现有返回值的线程
用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程 ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了. ...
-
Java基础之线程——管理线程同步方法(BankOperation2)
控制台程序. 当两个或多个线程共享同一资源时,例如文件或内存块,就需要采取措施,确保其中的一个线程不会修改另一个线程正在使用的资源.当其中的一个线程更新文件中的某个记录,同时另一个线程正在检索这个记录 ...
-
C# 多线程的自动管理(线程池) 基于Task的方式
C# 多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况: 1. 应用程序中线程把大部分的时间花费在等待状态,等待某个事件发生,然后给予响应.这一般使用 ThreadPool(线程 ...
-
学习pthreads,管理线程的栈
进程的地址空间分成代码段,静态数据段,堆和栈段.线程栈的位置和大小是从它所属的进程的栈中切分出来的.每个栈必须足够大,以容纳所有对等线程的函数的执行以及它们将会调用的例程链.或许你会问为什么要进行线程 ...
-
C#线程篇---线程池如何管理线程(6完结篇)
C#线程基础在前几篇博文中都介绍了,现在最后来挖掘一下线程池的管理机制,也算为这个线程基础做个完结. 我们现在都知道了,线程池线程分为工作者线程和I/O线程,他们是怎么管理的? 对于Microsoft ...
-
使用ExecutorCompletionService 管理线程池处理任务的返回结果
在我们日常使用线程池的时候,经常会有需要获得线程处理结果的时候.此时我们通常有两种做法. 1. 使用并发容器将callable.call() 的返回Future存储起来.然后使用一个消费者线程去遍历这 ...
-
[Swift实际操作]七、常见概念-(12)使用DispatchGroup(调度组)管理线程数组
本文将为你演示调度组的使用,使用调度组可以将多个线程中的人物进行组合管理,可以设置当多个相同层次的任务完成之后,再执行另一项任务. 首先导入需要使用的界面工具框架 import UIKit 在控制台输 ...
-
C#多线程学习(四) 多线程的自动管理(线程池)
在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPo ...
随机推荐
-
前阿里CEO卫哲谈阿里创业经验:如何找人、找钱、找方向?(不同的阶段分别有:时间优先、金额优先、比例优先,不要做平台,太难)
新浪科技李根 整理报道 卫哲现在是御嘉基金的创始合伙人,他另一个更加知名的身份是阿里巴巴(B2B)前CEO,在2006年到2011年的时间里,卫哲见证了阿里巴巴如何利用人才.资本和方向选择一路壮大. ...
-
Vim C/C++的一键编译
开始用Vim差不多有两个月的时间, 一开始用Makefile 编译一整个项目无压力, 但是当写到单个文件的时候, 编译就比较麻烦了, 每次都得 :w :!gcc -o 1.exe 1.c :!1 非常 ...
-
CSS当中数学表达式calc
CSS当中数学表达式calc 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路.本文将介绍calc()的相关内容 定义 数学表达式calc ...
-
docker组件介绍
一.Docker Client and Daemon(docker egine docker 引擎) docker是一个客户端工具,作用是发送 用户的请求给 dockerd 安装路径: /usr/bi ...
-
Servlet的三大作用域
Servlet的三大作用域 一.request 请求对象 共享的数据:请求共享 特点:同一次请求中,共享数据可以获取(请求一旦结束,请求共享清除站)(请求转发能共享参数,重定向不行) 代码:req. ...
-
0_Simple__simpleStreams
对比使用单流和多流(4条)情况下数据拷贝,以及数据拷贝加内核调用的效率差别.▶ 源代码 #include <stdio.h> #include <cuda_runtime.h> ...
-
Linux命令-定时任务命令:crontab
linux定时任务命令相当于windows=>附件=>系统工具=>计划任务程序. 要想让linux定时任务生效,首先应该先启动crond服务,并且给这个服务设置开机自自动. 默认li ...
-
(转)openstack 资源查询常用 sql
直接通过查询 openstack 数据库, 获得相应的常见查询结果 查询用户使用中主机, 及其主机对应信息 查询用户使用中存储, 及其存储对应信息 查询用户对应主机 mysql> select ...
-
由字符串反转(使用递归)引申出来一道Java面试题
如何面试一个从事编程工作的开发人员既困难又乏味,幸好还有很多值得参考的指南,比如:<Joel Guerilla Guide to interviewing>,但最后雇佣与否,还得由你自己决 ...
-
20165202 学习基础和c语言基础调查
你有什么技能比大多人(超过90%以上)更好? 我对自行车运动的兴趣始于初中时期,不敢说比大多数人更好,但在业余爱好者中相对来说还不错. 针对这个技能的获取你有什么成功的经验? 接触自行车运动几年里,我 ...