【问题标题】:Clojure: Create and manage multiple threadsClojure:创建和管理多个线程
【发布时间】:2017-10-17 03:09:08
【问题描述】:

我写了一个程序,它需要处理一个非常大的数据集,我打算在一台高端机器上用多个线程运行它。

我是 Clojure 的初学者,我迷失在无数可用的工具中 - 代理、期货、core.async(和 Quartzite?)。我想知道哪个最适合这份工作。

以下描述了我的情况:

  1. 我有一个函数可以转换一些数据并将其存储在数据库中。
  2. 上述函数的参数是从 Redis 集中弹出的。
  3. 只要 Redis 集中有值,就在多个单独的线程中运行该函数。

【问题讨论】:

    标签: multithreading clojure


    【解决方案1】:

    听起来你可能有一个 好的 embarrassingly parallel 问题 解决。在这种情况下,您可以简单地通过编写您的 处理成处理第一个数据的顶级函数。 一旦它起作用了,把它包起来 一个map 来处理所有的 数据顺序(串行,一次一个)。

    您可能想开始解决更大的问题,只需几个 数据集中的项目。这将使您的测试更顺畅 更快。

    map 工作后,是时候添加一个 p (并行)到你的代码来实现它 pmap。这是一个非常 有益的方式来加热你的 机器。 Here 是 关于 pmap 使用的线程数的讨论。


    以上是最简单的方法。如果您需要更好地控制 并发性, this concurrency screencast 探索 用例。

    【讨论】:

      【解决方案2】:

      如果不了解问题的详细信息,很难准确。您提到有几种选择:

      • 普通 Java 线程和线程池。如果您的问题与现有的 Java 解决方案相似,这可能是最直接的。
      • 简单的 Clojure 线程与 future 等。使用future 启动线程并在promise 中获得结果非常容易。
      • map 替换为pmap(平行图)。这可以在主要面向 map/reduce 的简单情况下提供帮助。
      • Claypoole 库:许多工具使多线程处理更简单、更容易。请参阅their GitHub projectClojure/West talk.

      【讨论】:

        【解决方案3】:

        为简单起见,期货是不可战胜的。他们创建一个新线程,并从中返回一个值。但是,您通常需要比它们提供的更细粒度的控制。

        core.async 库对并行性有很好的支持(通过管道,见下文),它还提供自动背压。您必须有一种方法来控制数据流,这样就不会有人因工作而挨饿,也不会因工作过多而负担过重。 core.async 通道必须是有界的,这有助于解决这个问题。此外,它是您问题的一个非常合乎逻辑的模型:从源中获取一个值,使用给定的parallelism 对其进行转换(可能使用transducer?),然后将结果放入您的数据库中。

        您也可以手动使用 Java 优秀的 j.u.concurrent 库。有用于thread pools 的低级原语以及thread management 工具。所有这些都可以在 clojure 中访问。

        从设计的角度来看,这取决于您是否更受 CPU 限制或 I/O 限制。这会影响决策,例如您是否将从 redis 执行并行读取并写入数据库。如果您受 CPU 限制,因此您的瓶颈是计算,那么并行化从 redis 读取或写入数据库将没有多大意义,不是吗?这些是需要考虑的类型。

        您确实有两个问题需要解决:(1) 您对 clojure/java 的并发机制的熟悉程度,以及 (2) 您解决此问题的方法(即,无论您使用哪种语言,您将如何解决此问题?)。一旦你解决了#2,你就会更好地了解我上面提到的使用哪些工具,以及如何使用它们。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-06-08
          • 1970-01-01
          • 2018-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多