Poco库使用:任务管理器TaskManager
文章目录
- 1.定义独立任务
- 2.使用TaskManager启动多个任务
- 3.TaskManager使用自定义线程池
- 4.添加任务观察者
- 5.使用自定义的任务观察者和任务通知
Poco库的任务管理器TaskManager有点像一个功能更加强大的线程池。我们定义的每一个Task以线程的形式运行在TaskManager中。TaskManager负责对运行的每个线程任务进行管理和监控。这里介绍一下任务管理器的用法。
1.定义独立任务
运行在TaskManager中的任务需要继承自Task类。我们可以给每个任务指定固定的名称。除了使用TaskManager对任务进行管理外,我们还可以将Task放到独立的线程中运行。为了方便外部的管理我们通过Task的setProgress()方法来控制任务的进度。
class TestTask : public Task
{public:TestTask() : Task("TestTask"){}void runTask(){_event.wait();if (sleep(10))return;//设置任务的进度 setProgress(0.5);_event.wait();//判断任务是否取消了if (isCancelled())return;//设置任务进度setProgress(1.0);_event.wait();}void cont(){_event.set();}
private://通过事件来对任务进行控制Event _event;
};void testFinish()
{//定义任务AutoPtr<TestTask> pTT = new TestTask;//开闭线程运行任务Thread thr;thr.start(*pTT);//控制任务的进度pTT->cont();while (pTT->progress() != 0.5) Thread::sleep(50);//取消任务pTT->cancel();//等待线程结束thr.join();//除了判断进度外我们还可以通过pTT->state()来查看任务状态//常用的状态包括://Task::TASK_RUNNING 任务运行中//Task::TASK_CANCELLING 任务取消//Task::TASK_IDLE 任务空闲//Task::TASK_FINISHED 任务结束
}
2.使用TaskManager启动多个任务
class SimpleTask : public Task
{public:SimpleTask() : Task("SimpleTask"){}void runTask(){sleep(10000);}
};
int main(int argc, char** argv)
{//启动任务TaskManager tm;tm.start(new SimpleTask);tm.start(new SimpleTask);tm.start(new SimpleTask);//结束任务TaskManager::TaskList list = tm.taskList();tm.cancelAll();while (tm.count() > 0) Thread::sleep(100);
}
3.TaskManager使用自定义线程池
通过引入自定义的线程池,我们可以对任务管理器中任务执行数量进行管理。
class SimpleTask : public Task
{public:SimpleTask() : Task("SimpleTask"){}void runTask(){sleep(10000);}
};
int main(int argc, char** argv)
{//最小线程数为2 最大线程数为5 线程的闲置时间为120sThreadPool tp(2, 5, 120);TaskManager tm(tp);//将线程池填充满for (int i = 0; i < tp.capacity(); ++i){tm.start(new SimpleTask);}//线程池和任务管理器任务数量的关系//tp.allocated() == tp.capacity()//tm.count() == tp.allocated()//等待线程结束tp.joinAll();
}
4.添加任务观察者
通过给任务管理器TaskManager添加观察者TaskObserver,我们可以对任务管理器中的任务运行状态进行监控。监控的内容包括:
1.任务是否启动
2.任务是否结束
3.任务进度
4.任务是否失败
namespace
{class TestTask : public Task{public:TestTask() :Task("TestTask"),_fail(false){}void runTask(){_event.wait();setProgress(0.5);_event.wait();if (isCancelled())return;if (_fail)throw SystemException("warp core breach detected");setProgress(1.0);_event.wait();}void fail(){_fail = true;}void cont(){_event.set();}private:Event _event;bool _fail;};class TaskObserver{public:TaskObserver() :_started(false),_cancelled(false),_finished(false),_pException(0),_progress(0.0){}~TaskObserver(){delete _pException;}void taskStarted(TaskStartedNotification* pNf){_started = true;pNf->release();}void taskCancelled(TaskCancelledNotification* pNf){_cancelled = true;pNf->release();}void taskFinished(TaskFinishedNotification* pNf){_finished = true;pNf->release();}void taskFailed(TaskFailedNotification* pNf){_pException = pNf->reason().clone();pNf->release();}void taskProgress(TaskProgressNotification* pNf){_progress = pNf->progress();pNf->release();}bool started() const{return _started;}bool cancelled() const{return _cancelled;}bool finished() const{return _finished;}float progress() const{return _progress;}Exception* error() const{return _pException;}private:std::atomic<bool> _started;std::atomic<bool> _cancelled;std::atomic<bool> _finished;Exception* _pException;float _progress;};}int main(int argc, char** argv)
{//添加不同任务状态的观察函数TaskManager task_manager;TaskObserver task_observer;task_manager.addObserver(Observer<TaskObserver, TaskStartedNotification>(task_observer, &TaskObserver::taskStarted));task_manager.addObserver(Observer<TaskObserver, TaskCancelledNotification>(task_observer, &TaskObserver::taskCancelled));task_manager.addObserver(Observer<TaskObserver, TaskFailedNotification>(task_observer, &TaskObserver::taskFailed));task_manager.addObserver(Observer<TaskObserver, TaskFinishedNotification>(task_observer, &TaskObserver::taskFinished));task_manager.addObserver(Observer<TaskObserver, TaskProgressNotification>(task_observer, &TaskObserver::taskProgress));//启动任务 AutoPtr<TestTask> pTT = new TestTask;task_manager.start(pTT.duplicate());Thread::sleep(200);pTT->cont();while (pTT->progress() != 0.5) Thread::sleep(50);//progress() == 0.5//state() == Task::TASK_RUNNINGTaskManager::TaskList list = task_manager.taskList();while (task_manager.count() == 1) Thread::sleep(50);//取消任务task_manager.cancelAll();bool is_canceled = task_observer.cancelled();//使任务失败结束pTT->fail();pTT->cont();
}
5.使用自定义的任务观察者和任务通知
为了在任务监控过程中传递更多的信息,实现更加细致化的监控,我们可以自定义任务观察者和任务通知。将更多的任务信息传递出来。自定义任务观察者和任务消息的实现方法如下:
namespace
{//通过模板指定消息内容形式template <typename T>class CustomNotificationTask : public Task{public:CustomNotificationTask(const T& t) :Task("CustomNotificationTask"),_custom(t){}void runTask(){sleep(10000);}//设置自定义消息 void setCustom(const T& custom){_custom = custom;postNotification(new TaskCustomNotification<T>(this, _custom));}private:T _custom;};template <class C>class CustomTaskObserver{public:CustomTaskObserver(const C& custom) : _custom(custom){}~CustomTaskObserver(){}void taskCustom(TaskCustomNotification<C>* pNf){_custom = pNf->custom();pNf->release();}const C& custom() const{return _custom;}private:C _custom;};
}int main(int argc, char** argv)
{TaskManager task_manager;//添加类型为int的自定义观察者 CustomTaskObserver<int> ti(0);task_manager.addObserver(Observer<CustomTaskObserver<int>, TaskCustomNotification<int> >(ti, &CustomTaskObserver<int>::taskCustom));//执行自定义任务AutoPtr<CustomNotificationTask<int> > pCNT1 = new CustomNotificationTask<int>(0);task_manager.start(pCNT1.duplicate());//设置任务消息for (int i = 1; i < 10; ++i){pCNT1->setCustom(i);}//添加类型为string的自定义观察者 CustomTaskObserver<std::string> ts("");task_manager.addObserver(Observer<CustomTaskObserver<std::string>, TaskCustomNotification<std::string> >(ts, &CustomTaskObserver<std::string>::taskCustom));AutoPtr<CustomNotificationTask<std::string> > pCNT2 = new CustomNotificationTask<std::string>("");task_manager.start(pCNT2.duplicate());std::string str("notify me");pCNT2->setCustom(str);
}
Poco库使用:任务管理器TaskManager相关推荐
- 基于 C++ POCO 库封装的异步多线程的 CHttpClient 类
用惯了 Jetty 的 基于事件的 HttpClient 类,在C++平台上也没找到这样调用方式的类库,只好自己写一个了. 目前版本 1.0,朋友们看了给点建议.(注:Kylindai原创,转载请注明 ...
- POCO库中文编程参考指南(11)如何使用Reactor框架?
1 Reactor 框架概述 POCO 中的 Reactor 框架是基于 Reactor 设计模式进行设计的.其中由 Handler 将某 Socket 产生的事件,发送到指定的对象的方法上,作为回调 ...
- Poco库使用:操作Json格式数据
文章目录 1.解析json字符串数据 2.生成Json格式的数据 3.操作Json数组 4.使用字符串流转换Json格式数据 5.使用键值检索Json结构中的数据 6.使用原始字符串避免字符转义 7. ...
- C++ 使用Poco库实现日志操作
C++ 使用Poco库实现日志操作 flyfish 文章目录 C++ 使用Poco库实现日志操作 日志输出到文件 日志输出到控制台 日志同时输出到文件和控制台 示例:将异常输出到日志 日志输出到文件 ...
- C++ 使用Poco库操作SQLite数据库
C++ 使用Poco库操作SQLite数据库 flyfish 文章目录 C++ 使用Poco库操作SQLite数据库 数据库插入记录 数据库插入记录方式2 数据库插入记录方式3 更方便的数据库插入记录 ...
- Poco库使用:文件目录操作
文章目录 获取各种标准目录 获取和应用相关的信息 目录操作 文件操作 在工程项目开发中,文件目录操作应该是最常见的操作之一了吧.这里就介绍一下如何通过Poco库实现各种文件目录操作. 获取各种标准目录 ...
- C++ 使用Poco库操作 json 文件
C++ 使用Poco库操作 json 文件 flyfish #include <string> #include <iostream> #include <sstream ...
- C++ 使用Poco库进行文件操作
C++ 使用Poco库进行文件操作 flyfish 环境: Ubuntu18.04 主要是Poco::File和Poco::Path #include <vector> #include ...
- C++ POCO库(访问数据库,版本问题,本人配置失败)
官网下载源码:https://pocoproject.org/ 一.POCO库简介 学习一个框架前,要先明白它的是什么,为什么,怎么用.下面这些文字,是从中文poco官网上转过来的,正如poco c+ ...
最新文章
- 快速上手笔记,PyTorch模型训练实用教程(附代码)
- Object-C时间与字符串的转化 因多语言设置中造成返回Nil的解决方法
- HDU 1003 Maxsum
- JS如何控制checkbox的全选反选
- proe输入数字时成双出现_职场数据控系列,超市基础篇,商品双ABC分析法及应用...
- SpringBoot 多种定时任务实现方式
- CStatic类简介
- 如何理解linux的平均负载?
- Coolite 开发心得
- 以太坊 solidity 教程
- 冲刺第七天 12.3 MON
- “ARP欺骗”木马病毒
- 宏碁电脑安装linux,ubuntu安装篇——acer 4750G ubuntu安装详解
- Xilinx平台SRIO介绍(汇总篇)
- Matlab之全局变量
- dialog在关闭的时候会刷新页面,并且地址后面多加了一个问号,导致数据查询不出来的解决方法
- Word中如何在指定页插入页眉(论文排版详细总结)
- CycleGAN的测试
- 小学奥数公式大全 学习奥数必备“工具”
- 第一届广西英招杯部分WP