【问题标题】:Concurrent programming techniques, pros, cons并发编程技术,优点,缺点
【发布时间】:2011-04-29 21:37:21
【问题描述】:

至少有三种众所周知的创建并发应用程序的方法:

  1. 通过锁定(.NET、Java)实现多线程和内存同步。软件事务内存 (link text) 是另一种同步方法。

  2. 异步消息传递(Erlang)。

我想了解是否有其他方法,并讨论这些方法应用于大型分布式应用程序的各种优缺点。我的主要关注点是简化程序员的生活。

例如,在我看来,当它们之间没有依赖关系时,使用多个线程很容易,这非常罕见。在所有其他情况下,线程同步代码变得非常麻烦并且难以调试和推理。

【问题讨论】:

  • 在您的列表中再添加一项:软件事务内存 (en.wikipedia.org/wiki/Software_transactional_memory)。还有一个 Java 版本可用:multiverse.codehaus.org
  • 作为子项添加到 1)。它看起来不像是编写并发应用程序的概念上的新方法,而是锁定结构的替代方案。
  • @Serge:我不确定我明白为什么它在概念上与消息传递的不同。
  • @Neeme:同样是 STM,参见 DeuceSTM sites.google.com/site/deucestm
  • @jalf:我只是看不出它会如何以任何剧烈的方式改变应用程序架构。它仍然依赖于线程和内存同步。我不确定事务语义是否比锁更容易使用共享状态。就个人而言,我对试图避免共享状态的概念非常感兴趣。

标签: java .net concurrency erlang


【解决方案1】:

我强烈建议您查看 Rich Hickey 的 this presentation。它描述了一种构建高性能并发应用程序的方法,我认为这种方法不同于基于锁或消息传递的设计。

基本上它强调:

  • 无锁、多线程并发应用程序
  • 不可变的持久数据结构
  • 软件事务内存处理的状态更改

并讨论这些原则如何影响Clojure 语言的设计。

【讨论】:

    【解决方案2】:

    阅读Herb SutterEffective Concurrency专栏,你也会有所启发。

    【讨论】:

    • 很棒的发现。虽然我很欣赏他对线程同步的深入研究,但他主要关注线程、锁定和原子操作,这只是并发的众多方法之一。他在几篇文章中提到了异步消息传递,但恕我直言,并没有走得太远。此外,他的文章显示了正确使用多线程是多么困难。我仍然对各种内存模型做噩梦。
    • 是的,Sutters 专栏明确关注使传统的基于锁的同步更易于管理,而不是探索替代技术。不过还是不错的读物。
    【解决方案3】:

    使用 Java 5 并发 API,只要您利用高级实用程序并正确使用它们,在 Java 中进行并发编程就不会变得繁琐和困难。我发现 Brian Goetz 的《Java Concurrency in Practice》一书是关于这个主题的优秀读物。在我的上一份工作中,我使用本书中的技术使一些图像处理算法扩展到多个 CPU 以及流水线 CPU 和磁盘绑定任务。我发现这是一次很棒的经历,我们取得了出色的成绩。

    或者,如果您使用 C++,您可以尝试使用 OpenMP,它使用 #pragma 指令使循环并行,尽管我自己从未使用过。

    【讨论】:

    • 请注意,并行和并发不是同义词。 tbb 还提供了parallel_forparallel_mapparallel_reduce,但对并发没有帮助。同样,也有一些语言,例如 newsqueak,是面向并发的,但不提供并行处理。
    • +1,好书和建议 - 现在您需要使用 Java 中的低级原语编写精巧、复杂的线程安全代码的情况非常罕见。审查和推理使用这些新 API 的代码也容易得多。
    • Microsoft 发布了带有 .NET 4.0 的 TPL,这是一组类似于 Java 的线程的更高级别抽象。虽然它确实简化了令人尴尬的并行问题的编码,但它对管理共享状态并没有多大帮助,反而会给你一种简单的错误印象。
    【解决方案4】:

    Erlang and OTP in Action中,作者提出了四种进程通信范式:

    • 带锁的共享内存

      构造(lock)用于 限制对共享资源的访问。 通常需要硬件支持 从记忆系统来看, 特殊说明。这种方法的可能缺点包括:开销、内存系统中的争用点、调试困难,尤其是在处理大量进程的情况下。

    • 软件事务内存

      内存被视为一个数据库事务决定要做什么 写和什么时候。这里的主要问题 由可能的表示 争论和数量 交易尝试失败。

    • 期货、承诺等

      基本思想是未来是一个 计算的结果 外包给不同的流程 (可能在不同的 CPU 或 机器)并且可以传递 像任何其他物体一样。的情况下 可能会出现网络故障问题。

    • 消息传递

      同步或异步,在 Erlang 风格

    【讨论】: