Ruby 2.3.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Fiberクラス

class Fiber

クラスの継承リスト: Fiber < Object < Kernel < BasicObject

要約

ノンプリエンプティブな軽量スレッド(以下ファイバーと呼ぶ)を提供します。他の言語では coroutine あるいは semicoroutine と呼ばれることもあります。 Thread と違いユーザレベルスレッドとして実装されています。

Thread クラスが表すスレッドと違い、明示的に指定しない限りファイバーのコンテキストは切り替わりません。またファイバーは親子関係を持ちます。Fiber#resume を呼んだファイバーが親になり呼ばれたファイバーが子になります。親子関係を壊すような遷移(例えば自分の親の親のファイバーへ切り替えるような処理)はできません。例外 FiberError が発生します。できることは

の二通りです。この親子関係は一時的なものであり親ファイバーへコンテキストを切り替えた時点で解消されます。

ファイバーが終了するとその親にコンテキストが切り替わります。

なお標準添付ライブラリ fiber を require することにより、コンテキストの切り替えに制限のない Fiber#transfer が使えるようになります。任意のファイバーにコンテキストを切り替えることができます。

例外

ファイバー実行中に例外が発生した場合、親ファイバーに例外が伝播します。

例:

f = Fiber.new do
  raise StandardError, "hoge"
end

begin
  f.resume     # ここでも StandardError が発生する。
rescue => e
  p e.message  #=> "hoge"
end

ショートチュートリアル

ファイバーは処理のあるポイントで他のルーチンにコンテキストを切り替え、またそのポイントから再開するという目的のために使います。 Fiber.new により与えられたブロックとともにファイバーを生成します。生成したファイバーに対して Fiber#resume を呼ぶことによりコンテキストを切り替えます。子ファイバーのブロック中で Fiber.yield を呼ぶと親にコンテキストを切り替えます。 Fiber.yield の引数が、親での Fiber#resume の返り値になります。

f = Fiber.new do
  n = 0
  loop do
    Fiber.yield(n)
    n += 1
  end
end

5.times do
 p f.resume
end

#=> 0
    1
    2
    3
    4

以下は内部イテレータを外部イテレータに変換する例です。実際 Enumerator は Fiber を用いて実装されています。

def enum2gen(enum)
  Fiber.new do
    enum.each{|i|
      Fiber.yield(i)
    }
  end
end

g = enum2gen(1..100)

p g.resume  #=> 1
p g.resume  #=> 2
p g.resume  #=> 3

注意

Thread クラスが表すスレッド間をまたがるファイバーの切り替えはできません。例外 FiberError が発生します。

f = nil
Thread.new do
  f = Fiber.new{}
end.join
f.resume
#=> t.rb:5:in `resume': fiber called across threads (FiberError)
       from t.rb:5:in `<main>'

特異メソッド

定義 説明
new {|obj| ... } -> Fiber

与えられたブロックとともにファイバーを生成して返します。ブロックは Fiber#resume に与えられた引数をその引数として実行されます。

yield(*arg = nil) -> object

現在のファイバーの親にコンテキストを切り替えます。

インスタンスメソッド

定義 説明
resume(*arg = nil) -> object

自身が表すファイバーへコンテキストを切り替えます。自身は resume を呼んだファイバーの子となります。

継承したメソッド

! != __id__ instance_eval instance_exec singleton_method_added singleton_method_removed singleton_method_undefined !~ <=> == === =~ __send__ _dump class clone define_singleton_method display enum_for eql? equal? extend freeze frozen? hash initialize initialize_copy inspect instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself marshal_dump marshal_load method method_missing methods nil? object_id pretty_inspect pretty_print pretty_print_cycle pretty_print_inspect pretty_print_instance_variables private_methods protected_methods psych_to_yaml public_method public_methods public_send remove_instance_variable respond_to? respond_to_missing? singleton_class singleton_method singleton_methods taint tainted? tap to_a to_ary to_hash to_int to_io to_proc to_regexp to_s to_str trust untaint untrust untrusted? .yaml_tag ::ARGF ::ARGV ::DATA ::ENV ::FALSE ::NIL ::RUBY_COPYRIGHT ::RUBY_DESCRIPTION ::RUBY_ENGINE ::RUBY_ENGINE_VERSION ::RUBY_PATCHLEVEL ::RUBY_PLATFORM ::RUBY_RELEASE_DATE ::RUBY_REVISION ::RUBY_VERSION ::SCRIPT_LINES__ ::STDERR ::STDIN ::STDOUT ::TOPLEVEL_BINDING ::TRUE

追加されるメソッド

定義 説明 ライブラリ
alive? -> bool

ファイバーが「生きている」時、真を返します。

fiber
current -> Fiber

このメソッドが評価されたコンテキストにおける Fiber のインスタンスを返します。

fiber
transfer(*args) -> object

自身が表すファイバーへコンテキストを切り替えます。

fiber