我正在考虑如何将“蚂蚁农场模拟器”从 Erlang 移植到 Erlang。这是基本的纲要:
1) 定义一个 100x100 的“插槽”世界
2)蚂蚁占用一个槽
3) 蚁群占据位置 50,50
4)食物在地图周围随机放置
5)蚂蚁一次移动一个空间寻找食物并将其带回殖民地
6) 一次只能在一个槽中放置一个对象。
这个问题的目标是尽可能保持系统并发。在 Clojure 中,上述问题通过拥有一个代理线程池来解决,每个代理为单个蚂蚁运行 AI。然后这些蚂蚁通过事务更新全局状态。
这是我一直在思考的全球状态。我们如何去构建“游戏世界”?
我的第一个想法是为每个蚂蚁创建一个 Erlang 进程,然后为地图中的每个插槽创建一个进程。要移动,蚂蚁会执行以下操作:
1)蚂蚁告诉它当前的位置“我想向北移动”
2) 插槽向北调用插槽并说“请更新您的内容以现在包含蚂蚁“pid””
3)如果北槽已经有一只蚂蚁,它会发送一个“拒绝”响应,该响应会向下渗透到包含蚂蚁的槽(然后是蚂蚁)。如果更新有效,那么“授权”会沿着链向下发送,并且蚂蚁会更新其内部状态。
我唯一不喜欢这种方法的是,在移动过程中,蚂蚁、它的槽和目标槽都被“锁定”,直到整个事务完成。然后,这会为死锁打开自己的大门。也就是说,两只蚂蚁可能同时试图交换位置,每个位置都在等待另一个位置。
任何人都可以提出更好的解决方案吗?
- -编辑 - -
让我逐步解决死锁问题:
1) Ant 1 请求 slot A “向北传输”到 slot 2 2) Ant 2 请求 slot B “向南传输”到 slot 1 3) Slot 1 向 slot 2 发送传输请求并等待回复 4) Slot 2向 slot 1 发送传输请求并等待回复
从代码的角度来看,这将很容易实现,但也会出现死锁,因为每个插槽只监听来自另一个插槽的回复。我想“正确的方法”可能是在转移过程中自动拒绝所有转移请求。