3

我们在工作中需要一个工作服务器,我目前正在玩 Quartz.net,但创建自己的想法对我很有吸引力。至少了解 Quartz.net 可能在幕后做的事情不会损害我更有效地使用它的理解/机会。

所以我的问题是你将如何在没有轮询的情况下在线程上获取和解雇工作?如果您每 2 分钟检查一次“工作商店”以查找需要解雇的工作,您可能会延迟大约 2 分钟。如果您减少轮询时间,则会增加您的工作商店的压力,并且仍然无法获得真正的开始时间。您可以在接下来的两分钟内预加载作业,并让线程在剩余时间内进入睡眠状态,以便它们在适当的时间开始,但如果您的轮询时间很长(删除、重新安排等),这似乎很笨拙并且容易出现问题。我正在剖析 Quartz 以弄清楚它是如何做到的,但我想知道我是否遗漏了一些基本的东西。

编辑:

像 Kevin 最初描述的线程结构似乎是你应该如何做一个工作服务器。它以最少的开销为您提供最大的灵活性。因为线程对于大多数人来说都是一个皮塔(也许只有我 :) 更简单的轮询示例将在 90% 的情况下完成工作,但代价是失去灵活性和更多开销。

另一方面,除非您将其设为单线程并执行单个作业,否则无论如何您都必须处理线程。还不如全力以赴,找出信号。

我也同意凯文的观点,即您在轮询数据库示例中声称免费获得的东西并不是真正免费的。如果它是线程/等待应用程序,您将像编写代码一样编写代码。如果您的轮询数据库作业服务器在作业过程中发生故障怎么办?两者都将依靠一些持久的存储来跟踪他们的状态以防发生灾难。

如果您将“jobstore”提升到一个抽象级别并且它不是基于正常的 ACID(正确的术语?)数据库会怎样。现在我相信你的很多“免费”东西都不再可用(交易?)。

4

1 回答 1

2

您将创建一个要触发的任务队列,按时间排序(最短到最长的时间)。将只有一个线程在队列的头部等待时间。当该时间到期时,您删除该项目并启动该任务。如果是重复任务,则重新计算并放回队列中。

唯一棘手的事情是线程应该根据一些条件变量等待。如果队列头发生变化,则可以向条件变量发出信号。通常使用条件变量,您可以判断它是否已发出信号与超时过期。因此,如果收到信号,您只需重新等待新的头部时间,否则超时表明是时候在队列头部运行任务了。

此解决方案意味着您只有一个线程来管理任务,而且它不是轮询的。

编辑:

我将更新我的解决方案,指出编写自己的调度程序可能不是一个好主意,因为石英是一个非常好的解决方案。另外我认为每秒轮询有点过头了,因为作业通常是按分钟运行,而不是按每秒运行。例如,您是否真的关心工作是否从 12:00:05 开始,或者 12:00:00 是否足够好?无论如何,您可以参数化您的轮询以满足所需的粒度级别。

于 2011-06-06T19:55:47.347 回答