设计模式:管理有限数量的资源 [英] Design Pattern: managing a limited number of a resource
问题描述
我正在设计一个系统功能的过程,我强烈地认为,必须有一个这样的模式,我应该知道在潜入代码之前。
场景是这样的:
- 我有一个资源池我的数量有限
- 我有不同数量的消费者使用这些资源;每个消费者只需要一个资源,并且在给定时间可能不会使用与任何其他消费者相同的资源。
- 消费者分为固定数量的组,系统需要以确保每个组中至少有一个资源。
- 每个组中的消费者数量随时间而变化;我们目前的做法是在启动时把资源分成两个堆栈:一个是紧急堆栈,一个是紧急堆栈和一个共同堆栈。紧急堆栈将包含与组相同数量的资源(因此,每个组都有一个资源)。剩余的可用资源进入公共堆栈。
当一个新的消费者即将被创建时,系统将请求一个资源。如果公共堆栈中有可用的资源,则会从中弹出一个资源并返回给调用者。如果公共堆栈为空,则可能会从紧急堆栈中弹出资源,而不是仅在同一组内的消费者没有紧急资源之前才能弹出。
无论何时一个组内的消费者都可以被重新分配,相关联的资源将被返回,并被推送到其中一个资源堆栈。负责取消分配消费者的代码将确保始终返回任何应急资源,以便在将资源重新推送到公共堆栈之前,紧急堆栈将被填充。
我觉得这是一个问题,应该存在一种经过测试和证明工作良好的设计模式,所以我呼吁社区:你知道这样一种模式吗?如果是这样的话,请你启发我。
更新
解决方案现在实现,使用这个问题的各种答案的一些零件。我发布了博客文章
解决方案我可能有一个资源堆栈,一组数组/地图,没有资源的组数。
分配...
如果group-count [group] == 0
从堆栈$ pop $资源
增量组计数[组]
减量保留计数
elseif保留 - 帐户< stack.size
来自栈的$ pop $资源
增量组计数[组]
其他
失败
关键是,堆栈永远不会小于仍然有权要求立即资源的组数。
这种方法的一个优点是,如果需要,您可以使其更加灵活。假设一个组有特殊要求,所以可能需要两个资源。
如果group-count [group]< ; group-reserved [group]
从堆栈
的资源
增量组计数[组]
减量保留计数
elseif保留计数< stack.size
来自栈的$ pop $资源
增量组计数[组]
其他
失败
在这种情况下,保留计数开始于所有group-reserved []值的总和。
这种情况下的释放逻辑是...
将资源推送到堆栈
减量组计数[组]
如果group-count [group]< group-reserved [group]
increment reserved-count
对于简单的情况,使用如果group-count [group] == 0。
I am in the process of designing a feature for a system where I strongly feel that there must be a pattern for this out there, that I should know about before diving into the code.
The scenario is this:
- I have a pool of resources of which I have a limited number.
- I have a variable number of consumers that use those resources; each consumer needs exactly one resource, and it may not use the same resource as any other consumer at a given time.
- The consumers are divided into a fixed number of groups, and the system needs to guarantee that there is a minimum of one resource for each group.
- The number of consumers in each group varies over time; they are allocated and deallocated as needed.
My current approach is to put the resources into two stacks at startup: one "emergency stack" and one "common stack". The emergency stack will contain the same number of resources as there are groups (so, one for each group). The rest of the available resources go into the common stack.
When a new consumer is about to be created, the system will request a resource. If there are resources available in the common stack, one will be popped from it and returned to the caller. If the common stack is empty, a resource may be popped from the emergency stack instead, but only if there are no consumers within the same group that already has an emergency resource.
Whenever a consumer within a group can be deallocated, the associated resource will be returned, and pushed onto one of the resource stacks. The code responsible for deallocating consumers will make sure to always return any emergency resources first, so that the emergency stack is filled, before returned resources are being pushed onto the common stack.
I feel that this is the sort of problem for which there ought to exist a design pattern that has been tested and proven to work well, so I call out to the community: do you know of such a pattern? If so, I kindly ask you to enlighten me.
Update
The solution is now implemented, using bits and pieces from various answers to this question. I published a blog post about it.
解决方案I'd probably have a single resource stack, an array/map keyed by group of counts, and a count of groups that have no resources.
To allocate...
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
The key point is that the stack is never allowed to get smaller than the number of groups that still have the right to demand an immediate resource.
One advantage to this approach is that you can make it a little more flexible if needed. Suppose one group has a special requirement, so it may need two resources at any point.
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
The reserved-count in this case starts as the sum of all group-reserved[] values.
The release logic for this case is...
push resource to stack decrement group-counts [group] if group-counts [group] < group-reserved [group] increment reserved-count
For the simple case, use "if group-counts [group] == 0".
这篇关于设计模式:管理有限数量的资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!