揭秘 Ruby "Fiber" 内部结构
Demystifying Ruby "Fiber" internals
我正在学习 Ruby Fiber
,它提供了很大的灵活性,但我对 Fiber 和 Ruby.
提出了一些疑问
require 'fiber'
class MyObj
def call_yield
print "Prepare to Yield"
print "foo bar"
Fiber.yield
print "Resumed"
@fiber = nil
end
def create_fiber
#@fiber = Fiber.new{call_yield}
@fiber = Fiber.new {}
p @fiber
end
def update
p @fiber.resume
end
end
obj = MyObj.new
# obj.call_yield #Fiber error
obj.create_fiber
obj.update
obj.update
当我取消注释带有 obj.call_yield
的行时,当我在 irb 会话中键入 Fiber.yield
时,Fiber 错误发生为 expected.Even,同样的错误发生。
- 如何ruby识别当前光纤是否有效?
- 包含
Fiber.Yield
的块的范围是什么给 Fiber.new
。
注意 create fiber 方法中的 #@fiber = Fiber.new{call_yield}
行仍然是有效代码。
- 我不知道那里发生了什么,因为函数是直接调用的,而不是作为符号调用的。
- 即使直接调用函数我在 screen.This 上也看不到任何内容显示函数内部的代码仍未启动 运行,但为什么会出现这种情况?
由于 fiber 是用 C 编写的,我没有其他来源可以消除我的疑问,因此请尽可能为每个问题提供简单的示例。
I want to know how Fiber.yield
behaves when inside block that is provided to Fiber.new
vs any other place in program ie)How it produces "root fiber error" elsewhere in program?
嗯,其实很简单。你需要做的就是在执行resume
时修改一块全局状态。例如,将当前纤程推送到全局堆栈或类似的东西。这是表现出相同行为的假光纤 class。
class MyFiber
class << self
def stack
@stack ||= []
end
def yield
top = stack.pop
if top.nil?
raise 'root fiber error'
end
puts "running fiber #{top}"
end
end
def initialize(&block)
@block = block
end
def resume
MyFiber.stack.push(@block)
@block.call
end
end
我正在学习 Ruby Fiber
,它提供了很大的灵活性,但我对 Fiber 和 Ruby.
require 'fiber'
class MyObj
def call_yield
print "Prepare to Yield"
print "foo bar"
Fiber.yield
print "Resumed"
@fiber = nil
end
def create_fiber
#@fiber = Fiber.new{call_yield}
@fiber = Fiber.new {}
p @fiber
end
def update
p @fiber.resume
end
end
obj = MyObj.new
# obj.call_yield #Fiber error
obj.create_fiber
obj.update
obj.update
当我取消注释带有
obj.call_yield
的行时,当我在 irb 会话中键入Fiber.yield
时,Fiber 错误发生为 expected.Even,同样的错误发生。- 如何ruby识别当前光纤是否有效?
- 包含
Fiber.Yield
的块的范围是什么给Fiber.new
。
注意 create fiber 方法中的
#@fiber = Fiber.new{call_yield}
行仍然是有效代码。- 我不知道那里发生了什么,因为函数是直接调用的,而不是作为符号调用的。
- 即使直接调用函数我在 screen.This 上也看不到任何内容显示函数内部的代码仍未启动 运行,但为什么会出现这种情况?
由于 fiber 是用 C 编写的,我没有其他来源可以消除我的疑问,因此请尽可能为每个问题提供简单的示例。
I want to know how
Fiber.yield
behaves when inside block that is provided toFiber.new
vs any other place in program ie)How it produces "root fiber error" elsewhere in program?
嗯,其实很简单。你需要做的就是在执行resume
时修改一块全局状态。例如,将当前纤程推送到全局堆栈或类似的东西。这是表现出相同行为的假光纤 class。
class MyFiber
class << self
def stack
@stack ||= []
end
def yield
top = stack.pop
if top.nil?
raise 'root fiber error'
end
puts "running fiber #{top}"
end
end
def initialize(&block)
@block = block
end
def resume
MyFiber.stack.push(@block)
@block.call
end
end