1
1

More than 3 years have passed since last update.

[Ruby]Fiberとはなんなのさ!

Posted at

Fiberとは

Fiberを利用することで複数のプログラム間で実行の中断や再開を相互に行わせることができます。
Fiberを用いると「ある処理を途中まで実行して、その後任意のタイミングで、前回の続きから処理を行う」みたいな処理の流れを扱うことが出来ます!

基本的な使い方

Fiberの作成

生成されたファイバは、Fiber#resumeメソッドにより実行を開始する必要があります。
ファイバの切り替えは自動的に行われないので、自分で切り替える必要があります。

fiber = Fiber.new {
  puts 'Hello, Fiber!'

  # 実行されたファイバから親に切り替える
  Fiber.yield

  puts 'Hello, (again)'
}

fiber.resume #=> "Hello, Fiber!"

fiber.resume #=> "Hello, (again)"

fiber.resume #=> FiberError: dead fiber called

引数と戻り値について

fiber = Fiber.new {|first|
  puts 'Hello, Fiber!'

  second = Fiber.yield('goodbye')

  puts second

  puts 'Hello, (again)'
}

puts fiber.resume('Hello, Fiber!') #=> "Hello, Fiber!"

puts fiber.resume(Hello, (again)) #=> "goodbye", "Hello, (agein)", "goodbye, (again)"

ジェネレーター

ジェネレーターとは、部分的な結果だけを計算して返し、続きを次回に計算することです。
これにより、実際の計算を最小限で済ませて、大きいデータを少ないリソースで扱うことが出来ます。

fiber = Fiber.new {
  a, b = 0, 1

  loop do
    a, b = b, a + b

    Fiber.yield(a)
  end
}

10.times.map { fiber.resume } #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
puts fiber.resume #=> "89"
puts feiber.resume #=> "144"

標準添付ライブラリを利用してより手軽に!

標準添付ライブラリでは、親子関係のないコルーチンとして扱うことが出来ます。
新たにFiber#transfer使えるようになるメソッドになります。
このメソッドは、ファイバの処理を移した際に、その後自動的に呼び出し元に戻らないということです。

require 'fiber'

f1 = Fiber.new {
  puts 'from f1'
}

f2 = Fiber.new {
  f1.transfer

  puts 'from f2'
}

# 生成されてからスタートしていないorブロックが終了していないときにtrue
f1.alive? #=> true

f2.resume #=> "from f1"
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1