设计模式:管理有限数量的资源

时间:2009-09-30 07:26:56

标签: language-agnostic design-patterns architecture

我正在为一个系统设计一个功能,我强烈地觉得必须有一个这样的模式,在进入代码之前我应该​​知道。

情景如下:

  • 我有一个资源池,我的数量有限。
  • 我有可变数量的消费者使用这些资源;每个消费者只需要一个资源,并且在给定时间可能不会使用与任何其他消费者相同的资源。
  • 消费者被划分为固定数量的群组,系统需要保证每个群体至少有一个资源。
  • 每组的消费者数量随时间而变化;它们根据需要进行分配和解除分配。

我目前的做法是在启动时将资源放入两个堆栈:一个“紧急堆栈”和一个“公共堆栈”。紧急堆栈将包含与组相同数量的资源(因此,每组一个)。其余可用资源进入公共堆栈。

当即将创建新的消费者时,系统将请求资源。如果公共堆栈中有可用资源,则会从中弹出一个资源并返回给调用者。如果公共堆栈为空,则可以从紧急堆栈中弹出资源,而不是,但前提是同一组中没有已有紧急资源的消费者

每当组中的使用者可以被释放时,将返回关联的资源,并将其推送到其中一个资源堆栈。负责解除分配消费者的代码将确保始终首先返回任何紧急资源,以便在将返回的资源推送到公共堆栈之前填充紧急堆栈。

我觉得这是一个问题,应该存在一个经过测试并证明效果很好的设计模式,所以我呼吁社区:你知道这样的模式吗?如果是的话,我请你赐教。

更新

现在使用来自该问题的各种答案的点点滴滴来实现解决方案。我发表了关于它的a blog post

5 个答案:

答案 0 :(得分:2)

我不知道任何模式,但我认为您可以简化您的方法:

如果您的资源池确实知道哪个组有资源,则您不需要额外的紧急堆栈。

  1. 提供同一堆栈中的所有资源。
  2. 如果可用资源的数量小于保证资源的数量 使用的保证资源的数量,如果请求组已有资源,则不返回资源。
  3. 除此之外,我认为你的方法简洁明了,我不相信有更好的方法。 (但我当然可能错了)

答案 1 :(得分:2)

我可能只有一个资源堆栈,一组按计数键入的数组/映射,以及没有资源的组计数。

分配......

if group-counts [group] == 0
  pop resource from stack
  increment group-counts [group]
  decrement reserved-count

elseif reserved-count < stack.size
  pop resource from stack
  increment group-counts [group]

else
  fail

关键是永远不允许堆栈小于仍有权要求直接资源的组数。

这种方法的一个优点是,如果需要,您可以使其更灵活一些。假设一个组有特殊要求,因此任何时候都可能需要两个资源。

if group-counts [group] < group-reserved [group]
  pop resource from stack
  increment group-counts [group]
  decrement reserved-count

elseif reserved-count < stack.size
  pop resource from stack
  increment group-counts [group]

else
  fail

在这种情况下,保留计数从所有group-reserved []值的总和开始。

此案例的发布逻辑是......

push resource to stack
decrement group-counts [group]
if group-counts [group] < group-reserved [group]
  increment reserved-count

对于简单的情况,请使用“if group-counts [group] == 0”。

答案 2 :(得分:2)

您还可以交换逻辑(可能会产生更清晰的代码):

从一开始就为每个组分配资源。将其余资源保留在“免费”资源列表中。 任何要求资源的消费者都是通过组资源分配器来实现的,该组资源分配器只是提供默认组资源或查询免费资源。 在返回资源时,首先填充组资源漏洞,然后开始填充免费资源列表。

所以你最终获得了一大堆免费资源。 每个组有一个资源分配器,可以访问空闲资源池和默认资源。 消费者与组分配器进行交互。

答案 3 :(得分:1)

这看起来像是一个非常奇怪的游泳池版本。

例如,如果默认池中有七个组和七个资源,则在“紧急”池中有七个。如果每个组请求一个资源,则默认池耗尽,然后如果任何一个组请求另外两个资源发生饥饿,则使用的十四个资源中只有八个。即使您将其更改为首先使用特定于组的资源,您仍然会发现只有8/14利用率的饥饿情况。

为什么资源的第二个请求应该是失败的而不是第一个请求(另一种看待“每个组至少有一个资源”的要求),这究竟是什么意思呢?

答案 4 :(得分:0)

这很有趣。在高级别,问题是您有两种类型的资源请求:不允许失败的高优先级请求,以及可能失败的标准请求。

处理此问题的一种可能方法是,您的消费者可以被暂停。如果可能,您可以在消费者和经理之间实现双向通信。

消费者可以请求资源或释放资源

经理可以撤销资源

当经理收到正常请求时,如果没有免费资源,它将拒绝该请求。如果它收到优先权请求,将强制撤销某些消费者(由某些适当的政策决定)。这类似于分布式锁系统的工作方式。这可以防止饥饿,但会大大增加复杂性,如果消费者在启动时必须完成运行,甚至可能无法实现。

如果做不到这一点,我认为达人的回答可能是最理想的,但是,如果一个群体中没有活跃的消费者,而另一个群体中有许多活跃的消费者,那么你仍然存在浪费。但是,可以通过对组进行良好的分区来缓解这种情况。