Tim*_*dge 6 concurrency erlang
我正在考虑如何将"蚁场模拟器"从Erlang移植到Erlang.这是基本的纲要:
1)定义一个100x100的"槽"世界
2)蚂蚁占据一个槽
3)蚁群占据50,50的位置
4)食物随机放置在地图上
5)蚂蚁每次移动一个空间寻找食物并将其带回殖民地
6)一次只能有一个对象在一个槽中.
此问题的目标是使系统尽可能保持并发.在Clojure中,上面的问题通过拥有一个代理程序的线程池来解决,每个代理程序运行一个蚁群的AI.然后这些蚂蚁通过交易更新全局状态.
这是我一直在思考的全球状态.我们如何构建"游戏世界"?
我的第一个想法是为每个蚂蚁创建一个Erlang进程,然后为地图中的每个插槽创建一个进程.要移动,蚂蚁会执行以下操作:
1)蚂蚁告诉它当前位置"我想向北移动"
2)插槽向北调用插槽,并说"请更新您的内容,现在包含蚂蚁"pid""
3)如果北槽已经有一个蚂蚁,它会发送一个"拒绝"的响应,然后向下流入包含蚂蚁(然后是蚂蚁)的插槽.如果更新有效,那么"授权"将在链中发送,并且ant会更新其内部状态.
我唯一不喜欢这种方法的是,在移动过程中,蚂蚁,它的插槽和目标插槽都被"锁定",直到整个交易完成.然后这会打开僵局.也就是说,两只蚂蚁可能试图同时交换位置,每个插槽都在等待另一个.
有谁能建议更好的解决方案?
- -编辑 - -
让我逐步解决死锁问题:
1)Ant 1要求插槽A"向北转移"到插槽2 2)Ant 2要求插槽B"向南转移"到插槽1 3)插槽1向插槽2发送转移请求并等待回复4)插槽2向插槽1发送转移请求并等待回复
从代码的角度来看,这将很容易实现,但也会死锁,因为每个插槽只是侦听来自另一个插槽的回复.我认为"正确的方法"可能是在传输过程中自动拒绝所有传输请求.
让你的蚂蚁向他要移动到的位置进行投射,请求移动许可。然后,蚂蚁等待演员响应,告诉它移动是否成功。如果移动成功,蚂蚁就会更新自己的状态以表明它位于新的位置。如果失败,他会再次执行他的搜索逻辑。如果你最终 A 和 B 试图交换插槽,你不会陷入僵局,但他们都会认为他们必须寻找其他选择。
如果您的网格被大量占用,您可能希望插槽执行轮询逻辑,向邻近的蚂蚁分发权限,告诉它们如果它们的逻辑引导它们到达那里,它们就可以进入。(想象一个网格上有 50x50-2 只蚂蚁,你就会明白为什么这是一个很好的逻辑改变。)
永远不要使用电话,除非你绝对、肯定、毫无疑问没有电话就无法生存。然后,如果同一类型的进程有可能相互调用,或者类型可以相互调用,请尽力消除它们。