【问题标题】:Sparse world structures in ErlangErlang 中的稀疏世界结构
【发布时间】:2012-04-24 07:24:43
【问题描述】:

我正在考虑如何将“蚂蚁农场模拟器”移植到 Erlang。这是基本的纲要:

1) 定义一个 100x100 的“插槽”世界

2) 蚂蚁占据一个槽

3) 蚁群占据位置 50,50

4) 食物在地图周围随机放置

5) 蚂蚁一次移动一格寻找食物并将其带回蚁群

6) 一次只能在一个槽中放置一个对象。

这个问题的目标是让系统尽可能地并发。在 Clojure 中,上述问题通过拥有一个代理线程池来解决,每个代理为单个蚂蚁运行 AI。然后这些蚂蚁通过事务更新全局状态。

这是我一直在思考的全球状态。我们如何去构建“游戏世界”?

我的第一个想法是为每个蚂蚁创建一个 Erlang 进程,然后为 map 中的每个插槽创建一个进程。为了移动,蚂蚁会做以下事情:

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 发送传输请求,等待回复

从代码的角度来看,这很容易实现,但也会出现死锁,因为每个插槽只监听来自另一个插槽的回复。我想“正确的方法”可能是在转移过程中自动拒绝所有转移请求。

【问题讨论】:

  • 我喜欢你的方法的一般声音,并同意你想避免致命的拥抱。也许你可以通过添加蚂蚁不能交换位置的规则来解决你的致命拥抱。相反,他们必须互相绕行,或者至少有一个绕行。也就是说,需要一只蚂蚁去邻近的空地。
  • 为什么请求必须是同步和阻塞的?您可以发送请求,然后坐下来等待消息,包括其他请求和您的请求的答案。

标签: concurrency erlang


【解决方案1】:

让你的蚂蚁向它要移动的位置施法,请求允许移动。蚂蚁然后等待一个演员响应,告诉它移动是否成功。如果移动成功,蚂蚁会更新自己的状态以指示他在新槽中。如果失败,他将再次执行他的搜索逻辑。如果你最终让 A 和 B 试图交换插槽,你不会陷入僵局,但他们都会认为他们必须寻找其他选择。

如果您的网格被大量占用,您可能希望插槽执行轮询逻辑,将权限分发给相邻的蚂蚁,告诉他们如果他们的逻辑将它们引导到那里,它们就可以进入。 (想象一个有 50x50-2 蚂蚁的网格,你就会明白为什么这是一个很好的逻辑变化。)

切勿使用电话,除非您绝对、肯定、毫无疑问地没有电话就无法生存。然后,如果同一类型的进程有可能相互调用,或者可以相互调用的类型,请努力摆脱它们。

【讨论】:

    【解决方案2】:

    我假设当它向北失败时,它会尝试不同的方向?那么僵局在哪里呢?

    如果现场非常拥挤,我可以想象饥饿,但不是死锁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 2010-11-02
      • 1970-01-01
      • 2020-11-23
      • 2013-12-05
      • 2011-04-22
      • 2015-07-03
      相关资源
      最近更新 更多