2010-02-10 67 views
8

我注意到了两种“消息传递”方法。一个我见过Erlang使用,另一个来自Stackless Python。据我所知,这里的区别阻塞通道vs异步消息传递

厄兰风格 - 邮件发送和排队到接收进程的邮箱。从那里他们在先进先出的基础上被删除。一旦第一个进程发送消息,就可以继续进行。

Python风格 - 进程A排队等待发送到进程B. B当前正在执行一些其他操作,所以A被冻结,直到B准备好接收。一旦B打开读取通道,A发送数据,然后它们都继续。

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

现在我还没有在框架/语言中编写大型程序,所以我想知道你的经验与此有关,如果这是我应该担心的。

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

回答

6

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

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

也可以反转它,生产者等待消费者来抓取N个下一个可用消息。

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

我认为异步消息传递与Erlang一样是更好的方法,因为当延迟很高时,您可能非常想避免在计算机之间进行消息传递时进行同步。然后,人们可以通过巧妙的方式来实现流量控制。比如说,要求制作人发送N封邮件时,要求消费者确认,或者不时发送一封特殊的“当我收到这封电子邮件时给我发电子邮件”信息,以便计算ping时间。

3

从广义上讲,这是无界队列vs有界队列。一个无堆栈通道可以被认为是一个0大小的队列的特例。

有界队列有死锁的倾向。两个线程/进程试图向对方发送消息,都使用完整队列。

无界队列有更微妙的失败。正如你所提到的,一个大邮箱不会满足延迟要求。走得够远,它最终会溢出;没有无限记忆这样的事情,所以它实际上只是一个有限的队列,具有极大的限制,可以在完成时中止进程。

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