2011-08-21 98 views
6

就性能而言,消息传递并发方案和基于锁的并发方案之间的区别究竟是什么?一个等待锁定的线程,所以其他线程可以运行。因此,我看不出消息传递如何比基于锁的并发更快。消息传递与锁定

编辑:具体地讲,我讨论一个消息传递方法等Erlang中,相比于使用锁(原子操作或)的共享数据的方法。

+0

是否有可能只是扩展你的问题?你究竟在问什么?案例的一些例子?因为'真正'回答你的问题 - 就像写一本书:) - 真的很长 –

+2

这是公平的比较吗?这不是苹果和橘子吗? –

+0

是关于比较传统线程和[SEDA](http://en.wikipedia.org/wiki/Staged_event-driven_architecture)类似方法的这个问题吗?如果是的话,那么我的理解是阻塞线程涉及显着的性能开销(内存隔离等)。你可以看看讨论:[如何显着提高Java性能?](http://programmers.stackexchange.com/questions/96994/how-to-sificificantly-improve-java-performance) – gnat

回答

1

当你想要做的只是锁定时使用消息传递是错误的。在这些情况下,使用锁定。然而,消息传递给你的不仅仅是锁定 - 正如其名称所暗示的,它允许你在线程或进程之间传递消息,即数据。

1

消息传递(使用不可变消息)更容易得到正确。通过锁定和共享可变状态,很难避免并发错误。

至于性能,最好自己测量一下。每个系统都不同 - 工作负载特性是什么,依赖于其他操作结果的操作,还是它们完全或大部分是独立的(这将允许大规模并行性),延迟或吞吐量更重要,有多少台机器等。锁定可能会更快,或者再次传递消息,或者完全不同。如果采用与LMAX相同的方法来解决手头的问题,那么也许可以。 (我将LMAX体系结构分类为消息传递,尽管它与基于actor的消息传递非常不同。)

8

正如其他人提出的(“苹果和橙子”),我将这两种技术看作正交。这里的基本假设似乎是一个会选择一个或另一个:我们要么使用锁定和共享资源我们将使用消息传递,并且一个呈现另一个不必要,或者其他甚至不可用。

很像,比如说,一个自循环直译器,但不是很明显这是真正的原语在这里。例如,为了实现消息传递,你可能会需要原子CAS和特定的存储可见性语义,或者一些锁和共享的状态。可以用锁来实现原子操作,或者可以在原子操作方面实现锁定(就像Java在其java.util.concurrent.locks类型中那样)。

同样,但无可否认的拉伸,一个可以实现与消息传递锁定。问一个更好的表现通常没有什么意义,因为这实际上是一个关于哪个建立在哪个方面的问题。最有可能的,这是在较低的水平一个可以通过编程能够比一个建在上面—由于一直采用手动变速器的汽车的情况下,直到驱动更好最近(相当多的辩论有太多)。

通常情况下,消息传递方式不称赞更好的性能,而是为了安全和方便,它通常通过拒绝锁定和共享资源的程序员控制销售。因此,它会针对程序员的能力而下注;如果程序员无法获得锁定,他不能很差地执行它,并减慢程序的执行速度。就像关于手动内存管理和垃圾收集的争论一样,有些人会声称是“好驱动程序”,充分利用手动控制;其他—特别是那些实施和促进使用垃圾收集器—的人将声称总体上,收集者可以比手动管理的“不太好的司机”做得更好。

没有绝对的答案。这里的区别在于程序员的技能水平,而不是他们可能使用的工具。

4

恕我直言,消息传递可能不完全是并发计划。它基本上是(IPC)进程间通信的一种形式,它是共享对象的替代方案。 Erlang支持将消息传递给共享对象。共享对象的

缺点(优点OD消息传递):

  • 易变/共享对象的状态是很难在多个线程同时运行一个上下文推理。
  • 在共享对象上同步将导致本身不是wait free或非lock free的算法。
  • 在多处理器系统中,可以跨处理器缓存复制共享对象。即使使用不需要同步的基于比较和交换的算法,也可能花费大量处理器周期将高速缓存一致性消息发送到每个处理器。
  • 由消息传递语义构建的系统本质上具有更高的可扩展性。由于消息传递意味着消息是异步发送的,发送者不需要阻塞,直到接收者作用于消息。共享对象(消息传递的缺点)的

优点:

  • 一些算法趋于简单得多。
  • 需要资源锁定的消息传递系统最终会退化为共享对象系统。在Erlang中,当程序员开始使用ets表等来存储共享状态时,这一点显而易见。
  • 如果算法是免等待的,您将看到改进的性能和减少的内存占用量,因为新消息形式的对象分配少得多。
0

消息传递不使用共享存储器,这意味着它不需要锁,引起每个线程(处理)只能加载或存储其自己的存储器,它们相互通信是发送&的方式接收消息。