我想知道什么样的数据结构/算法可能有助于处理以下情况;我不确定是否需要一个fifo、一个优先级队列或多个fifo。
我有n个对象必须通过预定义的工作流。每个对象必须完成步骤1,然后是步骤2,然后是步骤3,然后是步骤4,等等。每个步骤要么快速完成,要么包含一个依赖于外部事物完成的“等待”(例如文件操作的完成或其他)每个对象都保持自己的状态。如果我必须为这些对象定义一个接口,它应该是这样的(下面用伪java编写,但这个问题与语言无关):
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().
}
我需要编写一个单线程调度程序,对“下一个”对象调用executeStep()。我的问题是,我不确定应该使用什么技术来确定“下一个”对象是什么我希望公平(先到先得,不在等待状态的物品先得)。
我的直觉是有3个fifos,准备,等待和完成。在开始时,所有对象都放在就绪队列中,调度器重复一个循环,从就绪队列中取出第一个对象,调用executestep(),并将其放在与executestep()的结果相匹配的队列中。除了等待队列中的项在其状态更改时需要放入就绪或完成队列之外…啊!
有什么建议吗?
最佳答案
如果这必须是单线程的,那么您可以为ready和waiting对象使用一个fifo队列,并在每个对象出现时使用您的线程对其进行处理。如果它的状态更改为等待,那么只需将其粘回到队列中,然后将其重新处理。
类似于(psuedocode):
var item = queue.getNextItem();
var state = item.executeStep ();
if (state == WAITING)
queue.AddItem (item);
else if (state == DONE)
// add to collection of done objects
根据executestep运行所需的时间,您可能需要引入一个延迟(sleep not for)以防止出现紧密的轮询循环。理想情况下,您应该让对象发布状态更改事件并完全取消轮询。
这是在多线程广泛应用之前,在硬件和通信软件中常见的一种时间限制方法。