我应该使用哪些库来获得更好的OCaml线程?

Jac*_*ale 11 ocaml

我之前问过一个相关的问题为什么OCaml的线程被认为是"不够"?

无论ocaml的线程有多"糟糕",我都注意到一些图书馆说他们可以做真正的线程化.

例如,Lwt

Lwt提供了一种新的替代方案.它提供了非常轻量级的协作线程; "启动"一个线程是一个非常快速的操作,它不需要新的堆栈,新的进程或其他任何东西.此外,上下文切换非常快.事实上,我们将为每个系统调用启动一个线程非常容易.组成协作线程将允许我们编写高度异步的程序.

另外Jane Streetaync_core也提供了类似的事情,如果我是对的.


但我很困惑.做Lwtaync_core提供线程Java threading

如果我使用它们,我可以使用多个CPU吗?

以什么方式,我可以在OCaml中获得"真正的线程"(就像在Java中一样)?


编辑

我还是很困惑.

让我添加一个场景:

我有一个server(16 cpu cores)和一个服务器应用程序.

服务器应用程序的作用是:

  • 它会听取请求
  • 对于每个请求,它启动一个计算任务(假设花费2分钟完成)
  • 当每个任务完成时,任务将把结果返回给main,或者直接将结果发送回客户端

在Java中,它非常简单.我创建了一个线程池,然后对于每个请求,我在该池中创建一个线程.该线程将运行计算任务.这在Java中很成熟,它可以使用16个cpu内核.我对吗?

所以我的问题是:我可以在OCaml中做同样的事情吗?

gas*_*che 16

您引用的并行化服务器的示例是使用简单的多处理模型很好地解决的那些令人尴尬的并行问题之一fork.几十年来,这在OCaml中已经可行了,是的,如果需要,您可以使用机器的所有内核进行几乎线性的加速.

要使用标准库的简单原语来实现这一点,请参阅在线书籍"OCaml中的Unix系统编程"(2003年首次发布)的本章,和/或在线书"使用OCaml开发应用程序"的本章(第一章) 2000年发布).

您可能还想使用更高级的库,例如rad提到的Gerd Stolpmann的OCamlnet库,它提供了许多东西,从通常的客户端/服务器设计的直接助手到低级多进程通信库; 看文档.

Parmap也很有趣,但可能用于稍微不同的用例(更多的是你同时拥有大量可用的数据,你想要并行处理相同的函数):一个简单的重新加入的Array.mapList.map(或者fold),该并行化计算.

  • 杰克逊我已经回答了最后一个问题 (2认同)
  • 当我们谈论java的线程时,我们可能意味着我们将它们用于并行或并发.并行性示例:将大型工作拆分为N个任务并使线程单独工作.并发示例:在自己的线程中进行UI更新,以便昂贵的操作不会使UI无响应. (2认同)

rgr*_*erg 11

您将发现最接近真实(抢先)线程的是内置线程库.这意味着我的意思是你的编程模型将是相同的,但有两个重要的区别:

  • OCaml的本机线程不像Java那样轻量级.
  • 一次只执行一个线程,因此您无法利用多个进程.

这使得OCaml的线程成为并发或并行的非常糟糕的解决方案,因此通常人们避免使用它们.但他们仍然有自己的用途.

Lwt和Async非常相似,为您提供不同风格的线程 - 合作风格.协作线程与抢占式线程的不同之处在于,线程之间的上下文切换在代码中是显式的,并且阻塞调用始终从类型签名中显而易见.提供的协作线程非常便宜,因此非常适合并发,但同样不会帮助您使用parallelilsm(由于OCaml运行时的限制).

有关协作线程的详细介绍,请参阅此内容:http://janestreet.github.io/guide-async.html

编辑:对于您的特定情况,我将使用Parmap,如果任务的计算密集程度与您的示例相同,那么从parmap启动进程的开销应该可以忽略不计.

  • 要添加到rafix的注释:只有当你需要在进程之间需要快速可变共享内存时才会被搞砸. (2认同)