OCaml 5 带来对并发和共享内存并行性的支持

OCaml 5 的主要新特性

OCaml 5 引入了共享内存并行性和效果处理器的运行时支持,这些功能是异常处理、并发、异步 I/O 等的基础。

效果处理器(Effect Handlers)

效果处理器是一种用于表示和操作程序控制流的一级抽象。最直接的形式是提供可重启的异常机制,用于从错误中恢复。由于其灵活性,效果处理器还可以用于实现生成器、异步 I/O、并发等抽象。

效果类似于异常,但它们是可以通过构造函数实例化的(类型化)值,并且可以在执行后返回一个值。效果与效果处理器相关联,效果处理器是一个记录,包含三个字段:retc(处理计算结果的函数)、exnc(处理异常的函数)和effc(处理效果的泛型函数)。

效果的示例

以下是一个 Conversion_failure 效果的声明和处理器示例:

type _ Effect.t += Conversion_failure : string -> int Effect.t

match_with sum_up r
  { effc = (fun (type c) (eff: c Effect.t) ->
      match eff with
      | Conversion_failure s -> Some (fun (k: (c,_) continuation) ->
              Printf.fprintf stderr "Conversion failure \"%s\"\n%!" s;
              continue k 0)
      | _ -> None
    )
   }

效果的更多应用

效果不仅用于处理异常,还可以用于实现生成器、异步/等待、协程等。例如,以下是一个简化版的协程实现:

type _ Effect.t += Async : (unit -> 'a) -> unit Effect.t
               | Yield : unit Effect.t

let rec run : 'a. (unit -> 'a) -> unit =
fun main ->
  match_with main ()
  { retc = (fun _ -> dequeue ());
    exnc = (fun e -> raise e);
    effc = (fun (type b) (eff: b Effect.t) ->
        match eff with
        | Async f -> Some (fun (k: (b, _) continuation) ->
                enqueue (continue k);
                run f
        )
        | Yield -> Some (fun k ->
                enqueue (continue k);
                dequeue ()
        )
        | _ -> None
    )}

多核 OCaml 和并行性

多核 OCaml 是 OCaml 的扩展,支持跨多个核心的共享内存并行性。domain 是并行的基本单位,提供了两个基本原语:spawnjoin

示例:使用 spawnjoin

let square n = n * n
let x = 5
let y = 10

let _ =
  let d = Domain.spawn (fun _ -> square x) in
  let sy = square y in
  let sx = Domain.join d in
  Printf.printf "x = %d, y = %d\n" sx sy

高级抽象

多核 OCaml 在 spawnjoin 的基础上构建了更高级的抽象,如任务(tasks)和通道(channels)。任务通过 asyncawait 实现并行计算,而通道用于域之间的通信。

当前限制

OCaml 5 编译器目前仅支持 x86-64 和 arm64 架构,支持的操作系统包括 Linux、BSD、macOS 和 Windows/migw64。OCaml 团队计划在 2023 年恢复对其他架构的支持。

其他改进

OCaml 5 还包括对运行时系统、标准库的改进以及多项优化。更多详细信息可参考官方发布说明。

阅读 31
0 条评论