0Pricing
Ruby Academy · 课时

Ractor

真正的并行执行

Ractor 是 CoddyKit 上的免费 Ruby Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Ruby Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Ruby Academy 课程共包含 4 节课。

什么是 Ractor

Ractor(Ruby Actor)是 Ruby 3 引入的一种并发原语,可提供真正的并行。每个 Ractor 都会独立运行 Ruby 代码,因此两个 Ractor 可以同时使用两个 CPU 核心。

  • Ractor 不共享可变对象,从而避开 GVL 的限制。
  • 它们通过发送消息进行通信。

Ractor 目前仍处于实验阶段,因此 Ruby 在使用它们时会打印警告。

创建 Ractor

使用 Ractor.new 和一个代码块创建 Ractor。代码块会并行运行。使用 take 获取代码块的最终值。

r = Ractor.new do
  2 + 3
end

puts r.take

没有共享状态

最重要的规则是:Ractor 不能随意共享可变对象。Ractor 代码块不会像普通代码块那样捕获外部局部变量。您必须显式传入数据。

正是这种隔离让无需锁的并行执行变得安全。

传入参数

传给 Ractor.new 的参数会传递给代码块的参数。这是向 Ractor 发送数据的安全方式。

r = Ractor.new(10) do |x|
  x * x
end

puts r.take

发送消息

Ractor 拥有消息收件箱。使用 ractor.send(value) 发送消息,并在代码块内部使用 Ractor.receive 接收消息。

r = Ractor.new do
  msg = Ractor.receive
  "got: " + msg
end

r.send("hello")
puts r.take

推送与拉取

有两种通信方向:

  • 推送:使用 send 将消息传入 Ractor,再使用 Ractor.receive 读取。
  • 拉取:Ractor 使用 Ractor.yield 让出值,外部使用 take 读取。

两者结合后,Ractor 就可以组成流水线。

r = Ractor.new do
  Ractor.yield 1
  Ractor.yield 2
end

puts r.take
puts r.take

冻结对象与可共享对象

有些对象可以在 Ractor 之间共享,因为它们无法被修改:true、false、nil、数值、符号以及完全冻结的对象。

Ractor.make_shareable 会冻结对象图,使其能够安全共享。

data = Ractor.make_shareable([1, 2, 3])
puts "Frozen? " + data.frozen?.to_s

复制与移动

发送不可共享的对象时,并行执行单元默认会对其进行深度复制,这样两边各自拥有一份。您也可以使用 send(obj, move: true) 将其移动,这会转移所有权,并使原对象无法继续使用。

移动大型对象可以避免复制开销。

并行工作

将 CPU 密集型工作拆分到多个并行执行单元中,并收集结果。由于每个单元都独立运行,因此可以使用多个核心。

ractors = (1..3).map do |n|
  Ractor.new(n) do |x|
    x * 100
  end
end

results = ractors.map(&:take)
puts "Results: " + results.join(", ")

并行执行单元与线程对比

对比:

  • 线程共享内存并需要锁;并行执行单元彼此隔离,并需要通过消息通信。
  • 线程无法并行执行 Ruby 的 CPU 工作;并行执行单元可以。
  • 并行执行单元的限制更严格,因此可以避免许多并发错误。

代价是数据共享规则更加严格。

何时使用并行执行单元

在以下情况下请选择并行执行单元:

  • 您有 CPU 密集型工作,并希望在一个进程中使用多个核心。
  • 您希望通过隔离来避免共享状态错误。

请记住,它们仍属于实验性功能;接口可能发生变化,而且许多 Ruby 包目前还不支持并行执行单元。

快速检查

检查您对并行执行单元的理解。

回顾:并行执行单元

您学习了如何使用并行执行单元实现进程内并行:

  • Ractor.new 可以并行运行代码;take 可以获取其结果。
  • 可以通过参数或 send 传入数据,并使用 Ractor.receive 接收数据。
  • 对象会被复制或移动,而不是自由共享。
  • Ractor.make_shareable 会冻结数据,以便安全共享。

至此,Ruby 并发课程就完成了:线程、GVL、纤程和并行执行单元。

常见问题解答

「Ractor」课时是免费的吗?

是的 — 「Ractor」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Ruby Academy 课程的其余内容,请升级到 CoddyKit PRO。 Ruby Academy 课程共包含 4 节课。

「Ractor」这节课中我会学到什么?

真正的并行执行 你通过在浏览器中直接运行的动手代码来练习 Ruby Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Ruby Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Ruby Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「Ractor」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Ruby Academy 课中编写并运行代码吗?

能。每节 Ruby Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 线程
  2. 详解 GVL
  3. 纤程
  4. Ractor
← 返回 Ruby Academy