Concurrency Basics
Fiber Resume
A fiber pauses and resumes work at explicit yield points.
fiber
Fibers are cooperative: code switches between the caller and the fiber only when `yield` and `resume` are used.
Fiber Resume
fiber_resume.rb
Replay: real traced execution (multi-file project)
start = 2
sequence = Fiber.new do
first = start
Fiber.yield(first)
second = first + 1
Fiber.yield(second)
second + 1
end
first_value = sequence.resume
second_value = sequence.resume
final_value = sequence.resume
puts "start=#{start}"
puts "first=#{first_value}"
puts "second=#{second_value}"
puts "final=#{final_value}"
start = 1
sequence = Fiber.new do
first = start
Fiber.yield(first)
second = first + 1
Fiber.yield(second)
second + 1
end
first_value = sequence.resume
second_value = sequence.resume
final_value = sequence.resume
puts "start=#{start}"
puts "first=#{first_value}"
puts "second=#{second_value}"
puts "final=#{final_value}"
start = 5
sequence = Fiber.new do
first = start
Fiber.yield(first)
second = first + 1
Fiber.yield(second)
second + 1
end
first_value = sequence.resume
second_value = sequence.resume
final_value = sequence.resume
puts "start=#{start}"
puts "first=#{first_value}"
puts "second=#{second_value}"
puts "final=#{final_value}"
start ← 2, sequence ← ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩
1start→ 2 = 2 #@start=1, 523sequence→ ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩ = Fiber.new do4 first = start5 Fiber.yield(first)67 second = first + 18 Fiber.yield(second)910 second + 111end1213first_value = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩.resume14second_value = sequence.resumefirst ← 2
3sequence = Fiber.new do4 first→ 2 = start25 Fiber.yield(first)sequence ← ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩
4 first = start5 Fiber.yield(first)(empty)67 second = first + 18 Fiber.yield(second)910 second + 111end1213first_value→ 2 = sequence→ ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume14second_value→ 2 = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume15final_value→ 2 = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume1617puts "start=#{start2}"18puts "first=#{first_value2}"19puts "second=#{second_value2}"20puts "final=#{final_value2}"outputstart=2 first=2 second=2 final=2
start ← 1, sequence ← ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩
1start→ 1 = 123sequence→ ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩ = Fiber.new do4 first = start5 Fiber.yield(first)67 second = first + 18 Fiber.yield(second)910 second + 111end1213first_value = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩.resume14second_value = sequence.resumefirst ← 1
3sequence = Fiber.new do4 first→ 1 = start15 Fiber.yield(first)sequence ← ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩
4 first = start5 Fiber.yield(first)(empty)67 second = first + 18 Fiber.yield(second)910 second + 111end1213first_value→ 1 = sequence→ ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume14second_value→ 1 = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume15final_value→ 1 = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume1617puts "start=#{start1}"18puts "first=#{first_value1}"19puts "second=#{second_value1}"20puts "final=#{final_value1}"outputstart=1 first=1 second=1 final=1
start ← 5, sequence ← ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩
1start→ 5 = 523sequence→ ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩ = Fiber.new do4 first = start5 Fiber.yield(first)67 second = first + 18 Fiber.yield(second)910 second + 111end1213first_value = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (created)⟩.resume14second_value = sequence.resumefirst ← 5
3sequence = Fiber.new do4 first→ 5 = start55 Fiber.yield(first)sequence ← ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩
4 first = start5 Fiber.yield(first)(empty)67 second = first + 18 Fiber.yield(second)910 second + 111end1213first_value→ 5 = sequence→ ⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume14second_value→ 5 = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume15final_value→ 5 = sequence⟨Fiber A /tmp/execution/⟨tmp B⟩.rb:33 (suspended)⟩.resume1617puts "start=#{start5}"18puts "first=#{first_value5}"19puts "second=#{second_value5}"20puts "final=#{final_value5}"outputstart=5 first=5 second=5 final=5