目录
◆ V6.5版之前的并行检测方案
◆ V6.5版之前的并行检测方案存在的问题
◆ V6.5版本的并行检测方案
◆ 定时执行专家 - 简介
◆ 定时执行专家 - 最新版下载
一些用户说任务数量可能达到200个,让我比较惊讶,这个软件的设计之初并没有考虑这么多的任务数量。考虑这个用户的需求,我重新调整了检测触发器触发的多线程并发的算法。具体算法调整细节本文详细解释如下。
◆ V6.5版之前的并行检测方案
按照12种【触发器类型】创建 12个检测线程,每个线程负责一种触发器类型的触发检测。
触发器类型 | 触发检测线程 |
倒计时 | CheckTriggerFireThread_1 |
伴随软件启动 | CheckTriggerFireThread_2 |
空闲时间 | CheckTriggerFireThread_3 |
间隔时间 | CheckTriggerFireThread_4 |
具体时间 | CheckTriggerFireThread_5 |
每分钟 | CheckTriggerFireThread_6 |
每小时 | CheckTriggerFireThread_7 |
每天 | CheckTriggerFireThread_8 |
每周 | CheckTriggerFireThread_9 |
每月 | CheckTriggerFireThread_10 |
每年 | CheckTriggerFireThread_11 |
Cron表达式 | CheckTriggerFireThread_12 |
(表1,按照触发器种类,划分12个线程并发检查各类型触发器的触发条件)
按照触发器种类创建线程代码:
// start check firetime thread by trigger type
for (size_t i = 0; i< N_COUNT_TRIGGER_TYPE ; i++)
{
CheckTriggerFireThread* pworkerthread = new CheckTriggerFireThread(this, (NTriggerType)i);
if ( pworkerthread->Create() != wxTHREAD_NO_ERROR)
{
wxLogError(_("Can't create thread!"), _("Timing Executor"));
return;
}
if ( pworkerthread->Run() != wxTHREAD_NO_ERROR )
{
wxLogError(_T("Can't start thread!"), _("Timing Executor"));
return;
}
wxLogMessage(_T("%d ### CheckFireTimeThread[ThreadID_%zd]: %s Start >>>>>>"), wxDateTime::UNow().GetMillisecond(), (unsigned long long)pworkerthread->GetId(), Trigger::GetTypeNameByNTriggerType((NTriggerType)i));
}
◆ V6.5版之前的并行检测方案存在的问题
按照上面的并行检测方式,有一个问题是因为每个触发器类型的触发器数量分布不均匀,会导致检测效率比较低的现象,有的检测线程检测着很多触发器非常忙,有的线程很空闲。尤其在触发器数量比较多(比如:200个),并且数量集中在某几个触发器类型的时候。
◆ V6.5版本的并行检测方案
划定 6个触发器数量的区间,按照以下规则,创建线程数量和每个线程检测的触发器数量。触发器总数越多,创建的线程越多,每个线程检测的触发器数量也越多。
触发器数量区间代码:
// CountRange ThreadCount Every thread check trigger count
static const size_t N_TRIGGER_COUNT_RANGE_16 = 16; // 0 ~ 15, 4, 4, 90% user will in this range
static const size_t N_TRIGGER_COUNT_RANGE_32 = 32; // 16 ~ 31, 8, 4,
static const size_t N_TRIGGER_COUNT_RANGE_64 = 64; // 32 ~ 63, 8, 8,
static const size_t N_TRIGGER_COUNT_RANGE_128 = 128; // 64 ~ 127, 16, 8,
static const size_t N_TRIGGER_COUNT_RANGE_256 = 256; // 128 ~ 256, 16, 16,
触发器数量区间(TriggerCountRange) | 检测线程数量(ThreadCount) | 每个检测线程检测触发(CheckTriggerCount) | 检测线程Index范围(ThreadIndex) |
0 ~ 15 | 4 | 4 | 0 ~ 3 |
16 ~ 31 | 8 | 4 | 0 ~ 3 |
32 ~ 63 | 8 | 8 | 0 ~ 7 |
64 ~ 127 | 16 | 8 | 0 ~ 7 |
128 ~ 256 | 16 | 16 | 0 ~ 15 |
257 ~ | 16 | 16+ | 0 ~ 15 |
(表2,划定 6个触发器数量的区间,根据触发器总数确定线程数量、每个线程检测的触发器数量)
// start check firetime thread by thread index
for (size_t i = 0; i< nThreadCnt; i++)
{
CheckTriggerFireThreadEx* pworkerthread = new CheckTriggerFireThreadEx(this, nThreadCnt, i); // triggerid%nThreadCnt = i then check
if ( pworkerthread->Create() != wxTHREAD_NO_ERROR)
{
wxLogError(_("Can't create thread!"), _("Timing Executor"));
return;
}
if ( pworkerthread->Run() != wxTHREAD_NO_ERROR )
{
wxLogError(_T("Can't start thread!"), _("Timing Executor"));
return;
}
wxLogMessage(_T("%d ### CheckTriggerFireThreadEx[ThreadID_%zd, nThreadCnt_%zd, nThreadIdx_%zd, nCheckTriggerCnt_%zd] Start >>>>>>"), wxDateTime::UNow().GetMillisecond(), (unsigned long long)pworkerthread->GetId(), nThreadCnt, i, nCheckTriggerCnt);
}
- 检测算法:每个检测线程设置一个索引(ThreadIndex),按照区间最大值除以每个线程检测触发器数量(CheckTriggerCount)得到需要创建的线程数量(ThreadCount)。在检测线程里面,取得每个触发器的ID值除以线程索引(ThreadIndex)的余数,如果余数等于检测线程的索引值(ThreadIndex),就检测该触发器是否可以触发。
- 效果:每个检测线程需要检测的触发器数量比较平均,即使触发器总数达到 200以上,也会有不错的检测和触发效率。
◆ 定时执行专家 - 简介
制作精良、功能强大、毫秒精度、专业级的定时任务执行软件。软件具有 23 种【任务类型】、12 种【触发器】触发方式,并且全面支持界面化【Cron表达式】设置。软件采用多线程并发方式检测任务触发和任务执行,能够达到毫秒级的执行精度,可以同时支持50个以上任务的毫秒级触发。
(图1,定时执行专家 - 主界面)
◆ 定时执行专家 - 最新版下载
BoomWorks软件的最新版本_boomworks的博客-CSDN博客_boomworks
-- End --