Ruby 3.3 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Fiberクラス
クラス・モジュールの継承リスト: Fiber < Object < Kernel < BasicObject
ノンプリエンプティブな軽量スレッド(以下ファイバーと呼ぶ)を提供します。他の言語では coroutine あるいは semicoroutine と呼ばれることもあります。 Thread と違いユーザレベルスレッドとして実装されています。
Thread クラスが表すスレッドと違い、明示的に指定しない限りファイバーのコンテキストは切り替わりません。またファイバーは親子関係を持ちます。Fiber#resume を呼んだファイバーが親になり呼ばれたファイバーが子になります。親子関係を壊すような遷移(例えば自分の親の親のファイバーへ切り替えるような処理)はできません。例外 FiberError が発生します。できることは
の二通りです。この親子関係は一時的なものであり親ファイバーへコンテキストを切り替えた時点で解消されます。
ファイバーが終了するとその親にコンテキストが切り替わります。
Ruby 3.1 から 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>'
定義 | 説明 | |
---|---|---|
current -> Fiber
|
このメソッドが評価されたコンテキストにおける Fiber のインスタンスを返します。 |
|
new {|obj| ... } -> Fiber
|
与えられたブロックとともにファイバーを生成して返します。ブロックは Fiber#resume に与えられた引数をその引数として実行されます。 |
|
yield(*arg = nil) -> object
|
現在のファイバーの親にコンテキストを切り替えます。 |
定義 | 説明 | |
---|---|---|
alive? -> bool
|
ファイバーが「生きている」時、真を返します。 |
|
raise -> object
|
selfが表すファイバーが最後に Fiber.yield を呼んだ場所で例外を発生させます。 |
|
resume(*arg = nil) -> object
|
自身が表すファイバーへコンテキストを切り替えます。自身は resume を呼んだファイバーの子となります。 |
|
transfer(*args) -> object
|
自身が表すファイバーへコンテキストを切り替えます。 |
!
!=
__id__
__send__
instance_eval
instance_exec
method_missing
singleton_method_added
singleton_method_removed
singleton_method_undefined
!~
<=>
==
===
_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
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?
send
singleton_class
singleton_method
singleton_methods
tap
then
to_a
to_ary
to_hash
to_int
to_io
to_proc
to_regexp
to_s
to_str
.yaml_tag
::ARGF
::ARGV
::DATA
::ENV
::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