gpt4 book ai didi

ruby 纤维 : resuming transferred fibers

转载 作者:数据小太阳 更新时间:2023-10-29 07:15:52 25 4
gpt4 key购买 nike

我试图理解以下代码片段的行为。我特别关注 Fiber#transfer方法。

require 'fiber'

fiber2 = nil

fiber1 = Fiber.new do
puts "In Fiber 1" # 3
fiber2.transfer # 4
end

fiber2 = Fiber.new do
puts "In Fiber 2" # 1
fiber1.transfer # 2
puts "In Fiber 2 again" # 5
Fiber.yield # 6
puts "Fiber 2 resumed" # 10
end

fiber3 = Fiber.new do
puts "In Fiber 3" # 8
end

fiber2.resume # 0
fiber3.resume # 7
fiber2.resume # 9

我在右边用预期的连续执行顺序对代码行进行了编号。一次fiber3.resume返回,我调用 fiber2.resume , 我希望执行在 fiber2 内继续在标记为 #10 的行。相反,我收到以下错误:

fiber2.rb:24:in `resume': cannot resume transferred Fiber (FiberError)
from fiber2.rb:24:in `<main>'

这是 list 最后一行报告的错误:fiber2.resume .

最佳答案

似乎behavior has changed since Ruby 1.9 .虽然在 1.9 中,事情按照提问者假设的方式工作,但后来的 Ruby 版本改变了 #transfer 的工作方式。我在 2.4 上进行测试,但这可能适用于 2.* 系列中的早期版本。

在 1.9 中,#transfer 可用于在纤程之间来回跳转。有可能当时 #resume 不能用于此目的。无论如何,在 Ruby 2.4 中,您可以使用 #resume 从一根纤程跳转到另一根纤程,然后只需使用 Fiber.yield() 跳回到调用方.

示例(基于问题中的代码):

require 'fiber'

fiber2 = nil

fiber1 = Fiber.new do
puts "In Fiber 1" # 3
Fiber.yield # 4 (returns to fiber2)
end

fiber2 = Fiber.new do
puts "In Fiber 2" # 1
fiber1.resume # 2
puts "In Fiber 2 again" # 5
Fiber.yield # 6 (returns to main)
puts "Fiber 2 resumed" # 10
end

fiber3 = Fiber.new do
puts "In Fiber 3" # 8
end

fiber2.resume # 0
fiber3.resume # 7
fiber2.resume # 9

#transfer 的用例现在似乎是当你有两条光纤(我们称它们为 A 和 B)并且想要从 A 到 B,但你不打算来在 B 完成之前回到 A。然而,Ruby 没有尾调用优化的概念,所以 A 仍然必须等待 B 完成并产生它的最终值。尽管如此,#transfer 现在基本上是一张单程票。

关于 ruby 纤维 : resuming transferred fibers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38199283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com