博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程模型一:只完成最新任务
阅读量:5307 次
发布时间:2019-06-14

本文共 2019 字,大约阅读时间需要 6 分钟。

这个具体的应用场景就是QQ的历史记录管理器里面。当你点击某个联系人时,有个工作线程会去数据库查询对应的聊天记录,一次点击对应一个查询任务。

    1.当没有点击时,线程处于等待状态,一旦有点击,有查询任务,线程唤醒并执行任务。

    2.在线程执行过程中,如果用户又多次点击,只需要执行最后一个点击产生的查询任务即可。

    对应这个需求,我抽象出了一个多线程模型的实现。

OnlyRunNewestTask.h---------------------------begin--------------------------------

#pragma once

namespace ecs

{
namespace threadModal
{

class ECSUTIL_DllExport Task

{
public:
 virtual ~Task()
 {

 }

 virtual void Run() = 0;

};

class ECSUTIL_DllExport OnlyRunNewestTaskThread : public  ctk::SimpleThread

{
public:
 OnlyRunNewestTaskThread()
  :ctk::SimpleThread(0, "OnlyRunNewestTaskThread")
  ,m_mtx()
  ,m_pTask(NULL)
  ,m_updated(false)
  ,m_break(false)
 {
  
 };

 virtual ~OnlyRunNewestTaskThread() 

 {
  
 };

 void UpdateTask(Task* _data);

 bool GetTask(Task** task);
 void Break();

protected:

 virtual void run();

private:

 typedef ctk::Monitor<ctk::Mutex> _Mutex;

 _Mutex m_mtx; 

 Task* m_pTask; 
 bool m_updated;
 volatile bool m_break;
};

}

}

OnlyRunNewestTask.h---------------------------end--------------------------------

 

OnlyRunNewestTask.cpp---------------------------begin--------------------------------

#include "ecsutil_prec.h"

#include "ecsutil/threadModal/OnlyRunNewestTask.h"

using namespace ecs::threadModal;

void OnlyRunNewestTaskThread::UpdateTask(Task* _data)

 _Mutex::Lock lck(m_mtx);
 delete m_pTask;
 m_pTask = _data;
 m_updated = true;
 m_mtx.notify();
}

bool OnlyRunNewestTaskThread::GetTask(Task** task)

{
 _Mutex::Lock lck(m_mtx);
 if (!m_updated)
 {
  m_mtx.wait();
 }
 if (m_updated) 
 {
  *task = m_pTask;
  m_pTask = NULL;
  m_updated = false;
  return true;
 }
 return false;
}

void OnlyRunNewestTaskThread::Break()

{
 m_break = true;
 UpdateTask(NULL);
}

void OnlyRunNewestTaskThread::run()

{
 Task* taskData = NULL;
 while(GetTask(&taskData) && !m_break)
 {
  taskData->Run();
  delete taskData;
 }
}

OnlyRunNewestTask.cpp---------------------------end--------------------------------

 

    这种场景用这种解决方案是合适的。这个实现还有个缺点,在新任务来的时候,没有考虑中止执行旧任务。

    Task在这里就是个空壳,作用是为了抽离出独立的多线程模型代码。外界要使用这个实现代码,只需要写个具体的任务类,然后继承Task即可。要达到一样的效果,有没有更好的实现,求高手指教。

 

转载于:https://www.cnblogs.com/towik/p/3199691.html

你可能感兴趣的文章
Oracle层次查询
查看>>
vue调试工具之 vue-devtools的安装
查看>>
UCOS2_STM32F1移植详细过程(一)
查看>>
laravel的速查表
查看>>
5-24
查看>>
Javascript一些小细节
查看>>
Struct
查看>>
在WPF程序中使用摄像头兼谈如何使用AForge.NET控件(转)
查看>>
Linux修改用户shell
查看>>
[译]我是怎么构建Node.js程序的
查看>>
suse 源的添加与删除,以及源地址
查看>>
56个 PHP 开发常用代码片段(上)
查看>>
maven安装与项目移植
查看>>
大数据告诉你互联网到底有多大?完全超出你想象!
查看>>
C语言输入日期计算是该年的第几天
查看>>
Caliburn v2 变更-模块化
查看>>
Python之路,Day3 - Python基础3
查看>>
实验 4 在分支循环结构中调用自定义函数
查看>>
Java学习笔记-3.类与对象
查看>>
力扣——车的可用捕货量
查看>>