【发布时间】:2016-06-01 13:18:55
【问题描述】:
我正在尝试使用两个 Fiber 验证基本的产量/恢复模式。但是,产量/恢复机制似乎不起作用。我尝试了一些变体,但找不到我的错误。
预期的事件顺序:
- 启动线程(时间 0)
- 等到第一次返回(时间 +2 秒)
- 等到第二次返回(时间 +2 秒)
- 完成(时间 > +3 秒)
试试#1
#!/usr/bin/env ruby
require 'fiber'
f1 = Fiber.new do
puts "Fiber1 starting @ #{Time.new}."
fib1 = Fiber.current
Fiber.yield
sleep 2
puts "Fiber1 done @ #{Time.new}."
fib1.resume(1)
end
f2 = Fiber.new do
puts "Fiber2 starting @ #{Time.new}."
fib2 = Fiber.current
Fiber.yield
sleep 2
puts "Fiber2 done @ #{Time.new}."
fib2.resume(2)
end
puts "Waiting @ #{Time.new}."
r1 = f1.resume
puts "f1 back @ #{Time.new} - #{r1}."
r2 = f2.resume
puts "f2 back @ #{Time.new} - #{r2}."
sleep 1
puts "Done @ #{Time.now}."
这会导致:
Waiting @ 2016-06-01 06:15:52 -0700.
Fiber1 starting @ 2016-06-01 06:15:52 -0700.
f1 back @ 2016-06-01 06:15:52 -0700 - .
Fiber2 starting @ 2016-06-01 06:15:52 -0700.
f2 back @ 2016-06-01 06:15:52 -0700 - .
Done @ 2016-06-01 06:15:53 -0700.
添加第二个 resume 会导致 FiberError。
尝试#2
#!/usr/bin/env ruby
require 'fiber'
f1 = Fiber.new do
puts "Fiber1 starting @ #{Time.new}."
Fiber.yield
sleep 2
puts "Fiber1 done @ #{Time.new}."
1
end
f2 = Fiber.new do
puts "Fiber2 starting @ #{Time.new}."
Fiber.yield
sleep 2
puts "Fiber2 done @ #{Time.new}."
2
end
puts "Waiting @ #{Time.new}."
r1 = f1.resume
puts "f1 back @ #{Time.new} - #{r1}."
r2 = f2.resume
puts "f2 back @ #{Time.new} - #{r2}."
sleep 1
puts "Done @ #{Time.now}."
这会导致:
Waiting @ 2016-06-01 10:53:17 -0700.
Fiber1 starting @ 2016-06-01 10:53:17 -0700.
f1 back @ 2016-06-01 10:53:17 -0700 - .
Fiber2 starting @ 2016-06-01 10:53:17 -0700.
f2 back @ 2016-06-01 10:53:17 -0700 - .
Done @ 2016-06-01 10:53:18 -0700.
在这两种情况下,开始/结束时间相同,并且不返回结果。
【问题讨论】:
-
为什么您的光纤会自行调用 resume?
-
@FrederickCheung - 在没有 Fiber.current.resume 的情况下尝试过。仍然没有产生预期的结果,即:1)启动线程,2)等到第一次返回,3)等到第二次返回,4)完成。