Algorithm 用于调度工作流的数据结构?

Algorithm 用于调度工作流的数据结构?,algorithm,data-structures,scheduled-tasks,Algorithm,Data Structures,Scheduled Tasks,我想知道什么样的数据结构/算法可能有助于处理以下情况;我不确定我是否需要一个FIFO、一个优先级队列或多个FIFO 我有N个对象,它们必须通过预定义的工作流进行处理。每个对象都必须完成步骤1、步骤2、步骤3、步骤4等。每个步骤要么快速完成,要么包含一个“等待”,这取决于要完成的外部操作(如文件操作的完成或其他)。每个对象都保持自己的状态。如果我必须为这些对象定义一个接口,它应该是这样的(下面用伪Java编写,但这个问题与语言无关): 我需要编写一个单线程调度程序,在“next”对象上调用exec

我想知道什么样的数据结构/算法可能有助于处理以下情况;我不确定我是否需要一个FIFO、一个优先级队列或多个FIFO

我有N个对象,它们必须通过预定义的工作流进行处理。每个对象都必须完成步骤1、步骤2、步骤3、步骤4等。每个步骤要么快速完成,要么包含一个“等待”,这取决于要完成的外部操作(如文件操作的完成或其他)。每个对象都保持自己的状态。如果我必须为这些对象定义一个接口,它应该是这样的(下面用伪Java编写,但这个问题与语言无关):

我需要编写一个单线程调度程序,在“next”对象上调用executeStep()。我的问题是,我不确定应该使用什么技术来确定“下一个”对象是什么。我希望它是公平的(先到先得,为不处于等待状态的对象服务)

我的直觉是有3个先进先出,准备好,等待和完成。在开始时,所有对象都放置在就绪队列中,调度程序重复一个循环,将第一个对象从就绪队列中取出,调用executeStep(),并将其放置到与executeStep()的结果相适应的队列中。除了等待队列中的项目在其状态更改时需要放入就绪或完成队列之外。。。。啊


有什么建议吗?

注意-这并没有解决如何安排的问题,但我将使用一个单独的state类来定义状态和转换。对象不应该知道它们应该经历什么状态。他们可以被告知他们所处的“步骤”,等等

这也有一些模式

你应该读一点操作系统的知识,特别是调度器。您的示例是该问题的缩小集,如果您复制相关部分,它将非常适合您


然后,您可以添加优先级等。

注意-这并不能解决如何安排的问题,但我将使用一个单独的state类来定义状态和转换。对象不应该知道它们应该经历什么状态。他们可以被告知他们所处的“步骤”,等等

这也有一些模式

你应该读一点操作系统的知识,特别是调度器。您的示例是该问题的缩小集,如果您复制相关部分,它将非常适合您


然后可以添加优先级等。

任务对象从等待变为准备时,除了轮询它之外,没有任何方法通知您,因此等待队列和准备队列实际上可能只是其中之一。您只需依次对每一个调用executeStep()来循环它。如果作为executeStep()的返回值接收到DONE,则将其从该队列中删除,并将其粘贴到DONE队列中,然后将其忘掉

如果您想对就绪对象给予“更高的优先级”,并在浪费资源轮询等待之前尝试运行所有可能的就绪对象,您可以像您所说的那样维护3个队列,并且只在就绪队列中没有任何内容时处理等待队列


我个人会花费一些精力来消除对状态的轮询,而是定义一个接口,对象可以使用该接口在状态更改时通知您的计划程序。

任务对象从等待更改为准备时,您没有任何方法通知您,除非轮询它,因此,等待和准备就绪的队列可能只是其中之一。您只需依次对每一个调用executeStep()来循环它。如果作为executeStep()的返回值接收到DONE,则将其从该队列中删除,并将其粘贴到DONE队列中,然后将其忘掉

如果您想对就绪对象给予“更高的优先级”,并在浪费资源轮询等待之前尝试运行所有可能的就绪对象,您可以像您所说的那样维护3个队列,并且只在就绪队列中没有任何内容时处理等待队列


我个人会花费一些努力来消除州内的投票,而是定义一个接口,对象可以使用该接口在状态更改时通知您的计划程序。

如果必须是单线程的,您可以对准备和等待的对象使用单个FIFO队列,并在每个对象出现时使用线程处理它。如果它的状态变为等待,那么只需将它重新放入队列,它就会被重新处理

类似于(伪代码):

根据ExecuteTep运行所需的时间,您可能需要引入延迟(不适用于睡眠),以防止出现紧张的轮询循环。理想情况下,您应该让对象发布状态更改事件,并完全取消轮询


这是一种在多线程普及之前在硬件和通信软件中常见的时间限制方法

如果必须是单线程的,您可以对准备和等待的对象使用单个FIFO队列,并使用线程处理每个对象。如果它的状态变为等待,那么只需将它重新放入队列,它就会被重新处理

类似于(伪代码):

根据ExecuteTep运行所需的时间,您可能需要引入延迟(不适用于睡眠),以防止出现紧张的轮询循环。理想情况下,您应该让对象发布状态更改事件,并完全取消轮询


这是一种在多线程普及之前在硬件和通信软件中常见的时间限制方法

满足您问题中要求的最简单技术是重复迭代所有TaskObjects,对每个TaskObjects调用executeStep()

这只需要一个构造来保存TaskObjects,它可以是任何可移植的结构,例如数组

因为TaskObject
public interface TaskObject
{
   public enum State { READY, WAITING, DONE };
   // READY = ready to execute next step
   // WAITING = awaiting some external condition
   // DONE = finished all steps

   public int getCurrentStep();
   // returns # of current step

   public int getEndStep();
   // returns # of step which is the DONE case.

   public State getState();
   // checks state and returns it. 
   // multiple calls will always be identical, 
   // except WAITING which can transition to READY or DONE.

   public State executeStep();
   // if READY, executes next step and returns getState().
   // otherwise, returns getState().

}
var item = queue.getNextItem();
var state = item.executeStep ();
if (state == WAITING)
    queue.AddItem (item);
else if (state == DONE)
    // add to collection of done objects