文章目录

  • 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相关推荐

  1. 基于 C++ POCO 库封装的异步多线程的 CHttpClient 类

    用惯了 Jetty 的 基于事件的 HttpClient 类,在C++平台上也没找到这样调用方式的类库,只好自己写一个了. 目前版本 1.0,朋友们看了给点建议.(注:Kylindai原创,转载请注明 ...

  2. POCO库中文编程参考指南(11)如何使用Reactor框架?

    1 Reactor 框架概述 POCO 中的 Reactor 框架是基于 Reactor 设计模式进行设计的.其中由 Handler 将某 Socket 产生的事件,发送到指定的对象的方法上,作为回调 ...

  3. Poco库使用:操作Json格式数据

    文章目录 1.解析json字符串数据 2.生成Json格式的数据 3.操作Json数组 4.使用字符串流转换Json格式数据 5.使用键值检索Json结构中的数据 6.使用原始字符串避免字符转义 7. ...

  4. C++ 使用Poco库实现日志操作

    C++ 使用Poco库实现日志操作 flyfish 文章目录 C++ 使用Poco库实现日志操作 日志输出到文件 日志输出到控制台 日志同时输出到文件和控制台 示例:将异常输出到日志 日志输出到文件 ...

  5. C++ 使用Poco库操作SQLite数据库

    C++ 使用Poco库操作SQLite数据库 flyfish 文章目录 C++ 使用Poco库操作SQLite数据库 数据库插入记录 数据库插入记录方式2 数据库插入记录方式3 更方便的数据库插入记录 ...

  6. Poco库使用:文件目录操作

    文章目录 获取各种标准目录 获取和应用相关的信息 目录操作 文件操作 在工程项目开发中,文件目录操作应该是最常见的操作之一了吧.这里就介绍一下如何通过Poco库实现各种文件目录操作. 获取各种标准目录 ...

  7. C++ 使用Poco库操作 json 文件

    C++ 使用Poco库操作 json 文件 flyfish #include <string> #include <iostream> #include <sstream ...

  8. C++ 使用Poco库进行文件操作

    C++ 使用Poco库进行文件操作 flyfish 环境: Ubuntu18.04 主要是Poco::File和Poco::Path #include <vector> #include ...

  9. C++ POCO库(访问数据库,版本问题,本人配置失败)

    官网下载源码:https://pocoproject.org/ 一.POCO库简介 学习一个框架前,要先明白它的是什么,为什么,怎么用.下面这些文字,是从中文poco官网上转过来的,正如poco c+ ...

最新文章

  1. 快速上手笔记,PyTorch模型训练实用教程(附代码)
  2. Object-C时间与字符串的转化 因多语言设置中造成返回Nil的解决方法
  3. HDU 1003 Maxsum
  4. JS如何控制checkbox的全选反选
  5. proe输入数字时成双出现_职场数据控系列,超市基础篇,商品双ABC分析法及应用...
  6. SpringBoot 多种定时任务实现方式
  7. CStatic类简介
  8. 如何理解linux的平均负载?
  9. Coolite 开发心得
  10. 以太坊 solidity 教程
  11. 冲刺第七天 12.3 MON
  12. “ARP欺骗”木马病毒
  13. 宏碁电脑安装linux,ubuntu安装篇——acer 4750G ubuntu安装详解
  14. Xilinx平台SRIO介绍(汇总篇)
  15. Matlab之全局变量
  16. dialog在关闭的时候会刷新页面,并且地址后面多加了一个问号,导致数据查询不出来的解决方法
  17. Word中如何在指定页插入页眉(论文排版详细总结)
  18. CycleGAN的测试
  19. 小学奥数公式大全 学习奥数必备“工具”
  20. 第一届广西英招杯部分WP

热门文章

  1. 票总管代账版行业解决方案
  2. NOI / 1.13编程基础之综合应用 21:最大质因子序列
  3. ABAP 企业微信ASE 加密算法
  4. 学计算机文理不分,新高考文理不分科怎么上课 文理不分科还分班吗
  5. 漫步者 lollipods 充电
  6. java故事之致敬坚持梦想的人
  7. c++ 中字符串的字符数与字节数
  8. Linux命令——统计文件的字符数、字节数及行数
  9. Python正则表达式一文详解+实例代码展示
  10. python数据挖掘-oneR算法