我正在寻找适用于“洗碗机工作”问题的算法。
虽然能够将脏咖啡杯等放入其中是很棒的,但您很快就会遇到“菜肴状态如何?”困境。如果你走到厨房,你可以从洗碗机中取出菜肴,因为它们很干净而且没有放好吗?你可以把一个脏盘放在洗碗机里,还是会使干净的盘子无效?
这似乎是一个必须具有编程等效的问题。您有一个异步触发的共享进程,并将对象从一个状态移动到另一个状态。您需要能够在任何给定时间知道对象的状态。可以应用哪些算法?
我的开始选择是在洗碗机上创建一个“清洁”和“脏”的翻转标志。当洗碗机清空时,必须将其切换为“脏”,当它运行时必须切换到“清洁”。这个算法有问题吗?是否有更好/更少错误?
注意:请不要使用轮询时间表的算法......
答案 0 :(得分:6)
当User
线程想要将脏Dish
放入干净的洗碗机中时,会出现问题中的主要问题。
解决方案很简单。创建另一个Dishwasher
对象。
一个Dishwasher
拿着脏盘子,等待清理它们,另一个拿着最近洗过的盘子。
当持有干净餐具的Dishwasher
为空时,开始清洁另一个Dishwasher
中的脏盘子。
此时,User
个线程现在可以将脏菜放入干净的Dishwasher
(现在为空)。
继续无限期地交替使用两个Dishwashers
的角色。 User
线程总是可以放弃脏盘而不需要KitchenCounterBuffer
。
注意:此解决方案无法解决杯子饥饿问题。 User
线程仍然可能阻止等待洗碗机完成清洁。
注意2:在Dishwasher
为单身的受限制环境中,提供KitchenCounterBuffer
以及DishwasherOperator
来收集餐具并将KitchenCounterBuffer
的脏菜放入Dishwasher
。 KitchenCounterBuffer
然后在上面的算法中扮演脏Dishwasher
的角色。但是,这可能会导致User
个线程抛出异常或死亡。
答案 1 :(得分:2)
没有编程相关但它可能有助于解答您的逻辑问题...我的洗碗机有一个“清洁”灯,当你运行洗衣机时会出现。如果您只是短时间打开门(即取出一个干净的杯子),灯会一直亮着,但是如果您长时间打开门(有足够的时间清空洗衣机),灯会熄灭。 它并不完美,但它比前面的旗帜更可靠,必须被(有点健忘的)人类翻转。
答案 2 :(得分:1)
我假设洗碗机中的所有物品必须干净或脏,但不能混合搭配。下面的解决方案强制执行该属性。如果没有,你的比喻就不太对了。
只需要几个互斥量即可。
你有四种状态。
你可以进一步折叠空虚和肮脏,因为你不关心差异。
这假设您可以知道洗碗机什么时候是空的,如果没有,您需要在发信号DirtyMutex之前等待的ElementsInDishwasher的计数信号量。
答案 3 :(得分:1)
我喜欢你的比喻,但潜在的问题让我担心。根据我的经验,精心设计的系统总是知道(通常含蓄地)你所指的那种状态。例如,共享资源队列中的资源可供其他进程使用 - 如果不是,则不会在队列中。或者,由工作线程修改的资源处于线程处理所处的任何状态 - 更重要的是,没有其他线程需要来知道它是“干净”还是“脏”。
有一些令人难以置信的有效设计模式,我还没有遇到(或发明:-),但你所描述的有设计气味(或脏菜)的暗示,而不是有效的模式
答案 4 :(得分:1)
也许Finite State Machine符合您要解决的问题?
答案 5 :(得分:1)
只是制定一个规则,总是从洗碗机中取出干净的餐具,所以任何脏的东西都可以添加更多
答案 6 :(得分:1)
看,这是程序性思维的问题。它将一切都变成了一个批处理过程,而这在异步的,事件驱动的世界中并不能很好地发挥作用。你需要开始担心状态,线程,竞争条件,持久性等等。
避免这些问题的解决方案是让所有菜肴都不可变。如果你需要一个脏盘子,你只需创建一个带有污垢的新实例。
如果获得一个干净的菜肴副本是一种常见的操作(听起来就像你的情况),你可以在Dish对象中添加一个.AsClean()方法,它会自动为你返回一个干净的克隆。如果性能成为瓶颈,如果实例已经清理,可以通过返回this
来优化。
当然,这假设您处于具有合理堆空间和自动垃圾收集的环境中。
答案 7 :(得分:1)
我见过商用洗碗机通过隧道在传送带上送菜。你把脏盘子放在左边的架子上。你从右边的架子上取出干净的盘子。单个盘子的清洁/脏污状态与其在机器内的物理位置相对应。
这是一个完全不同的架构。使用标准洗碗机,您会将“清洁/脏”视为洗碗机的属性。 “清洁”意味着“不含脏菜”。使用传送式洗碗机,“清洁/脏”不是洗碗机的属性。
您可能不想切换到此体系结构,但如果这样做,请考虑通过并发阻塞队列连接的一系列处理对象。一道菜进入预冲洗机,出来,进入洗衣机,出来,进入烘干机,然后出来。
答案 8 :(得分:0)
您只需要一个标志,如您所示(清洁/脏)。洗碗机通常已经提供了这种机制:(物理)锁定。
从软件的角度来说,锁只是能够将餐具放入洗碗机中 - 你知道根据它是否被锁定而被移除的菜是干净还是脏,但只能放一个菜如果它解锁了如果你拿最后一道菜,你就解锁了。
答案 9 :(得分:0)
对此的一个简单解决方案是维护始终为真的不变量。这种不变量集的一个例子可以是:
对象的工作是与洗碗机交互以使这些不变量保持有序。如果有人在洗碗机中加入一个杯子并使其充满,他也必须将其打开,以便下一个到处的人会发现洗碗机已经满了,所有的杯子都是干净的。
答案 10 :(得分:0)
在洗涤周期结束时,您是否可以让洗碗机自动弹出餐具?
这与Mark Lutton的想法相似,类似于将清洁过的菜肴推到已知清洁餐具的(可能是临时的)队列中,然后可以将它们出列。
答案 11 :(得分:0)
这是因使用衰减技术而产生的设计问题 - 通过将设计的一部分更新为更高级的形式,您可以摆脱整个问题并节省时间,水和能源。
使用可食用的盘子?