阻塞通道与异步消息传递

时间:2010-02-10 19:32:54

标签: python erlang actor stackless python-stackless

我注意到了两种“消息传递”的方法。一个我见过Erlang使用,另一个来自Stackless Python。据我所知,这是差异

Erlang Style - 邮件被发送并排队到接收进程的邮箱中。从那里它们以FIFO为基础被移除。一旦第一个进程发送消息,它就可以继续。

Python样式 - 进程A队列向上发送到进程B.B当前正在执行其他一些操作,因此A被冻结,直到B准备好接收为止。一旦B打开读取通道,A发送数据,然后它们都继续。

现在我看到Erlang方法的优点是你没有任何被阻止的进程。如果B永远无法接收,A仍然可以继续。但是我注意到在我编写的一些程序中,由于消息的流入量大于流出量,因此Erlang消息框可能会充满数百(或数千)个消息。

现在我还没有用框架/语言编写大型程序,所以我想知道你的经历是这样的,如果这是我甚至应该担心的事情。

是的,我知道这是抽象的,但我也在寻找相当抽象的答案。

2 个答案:

答案 0 :(得分:7)

我在Erlang编程方面的经验是,当您期望高消息传递率(即生产者比消费者更快)时,您可以添加自己的流量控制。一个简单的场景

  • 消费者将:发送消息,等待确认,然后重复。
  • 制作人将:等待消息,在收到并处理消息时发送确认,然后重复。

还可以将其反转,制作人等待消费者前来获取N个下一个可用消息。

这些方法和其他流控制可以隐藏在函数后面,第一个大多数已经在gen_server:call/2,3中针对gen_server OTP行为过程提供。

我认为Erlang中的异步消息传递是更好的方法,因为当延迟很高时,您可能非常希望在计算机之间进行消息传递时避免同步。然后,人们可以通过巧妙的方式实现流量控制。比如说,要求消费者为生产者发送的每N条消息提供一个确认消息,或者发送一个特殊的“当你收到这封消息后立即ping我”消息,以计算ping时间。

答案 1 :(得分:4)

从广义上讲,这是无限队列与有界队列。无堆栈通道可以被认为是0大小的队列的特殊情况。

有界队列容易陷入僵局。两个线程/进程试图相互发送消息,两者都有一个完整的队列。

无限队列有更微妙的失败。如您所述,大邮箱不符合延迟要求。走得足够远,它最终会溢出;没有无限内存这样的东西,所以它实际上只是一个有限的队列,有一个巨大的限制,在完整时中止进程。

哪个最好?这很难说。这里没有简单的答案。