このマニュアルは既にメンテナンスが終了したバージョンの Ruby を対象としています。 最新版のマニュアルへ

Ruby 1.8.7 リファレンスマニュアル

スレッド

スレッドとはメモリ空間を共有して同時に実行される制御の流れです。 Ruby ではスレッドはThread クラスのインスタンスとして表されます。

実装

Ruby のスレッドはユーザレベルで実装されており、全プラットホーム上において同じ挙動を示します。 Ruby インタプリタは時分割でスレッドを実行しますので、スレッドを使うことで実行速度が速くなることはありません。

スケジューリング

Ruby のスレッドスケジューリングは優先順位付のラウンドロビンです。一定時間毎、あるいは実行中のスレッドが権利を放棄したタイミングでスケジューリングが行われ、その時点で実行可能なスレッドのうち最も優先順位が高いものにコンテキストが移ります。

メインスレッド

プログラムの開始と同時に生成されるスレッドを「メインスレッド」と呼びます。なんらかの理由でメインスレッドが終了する時には、他の全てのスレッドもプログラム全体も終了します。ユーザからの割込みによって発生した例外はメインスレッドに送られます。

スレッドの終了

スレッドの起動時に指定したブロックの実行が終了するとスレッドの実行も終了します。ブロックの終了は正常な終了も例外などによる異常終了も含みます。

例外発生時のスレッドの振る舞い

あるスレッドで例外が発生し、そのスレッド内で rescue で捕捉されなかった場合、通常はそのスレッドだけがなにも警告なしに終了されます。ただしその例外で終了するスレッドを Thread#join で待っている他のスレッドがある場合、その待っているスレッドに対して、同じ例外が再度発生します。

begin
  t = Thread.new do
    Thread.pass    # メインスレッドが確実にjoinするように
    raise "unhandled exception"
  end
  t.join
rescue
  p $!  # => "unhandled exception"
end

また、以下の 3 つの方法により、いずれかのスレッドが例外によって終了した時に、インタプリタ全体を中断させるように指定することができます。

上記3つのいずれかが設定されていた場合、インタプリタ全体が中断されます。

スレッド終了時の ensure 節の実行

スレッド終了時には ensure 節が実行されます。これはスレッドが正常に終了する時はもちろんですが、他のスレッドから Thread#kill などによって終了させられた時も同様に実行されます。 Thread#kill! が呼ばれた時はensure 節が実行されません。

ただしメインスレッドに対して Thread#kill! が呼ばれても ensure 節が実行されます。メインスレッドの終了時の詳細に関しては 終了処理 を参照して下さい。

スレッドの状態

個々のスレッドは、以下の実行状態を持ちます。これらの状態は Object#inspectThread#status によって見ることができます。

p Thread.new {sleep 1} # => #<Thread:0xa039de0 sleep>
run (実行or実行可能状態)

生成されたばかりのスレッドや Thread#runThread#wakeup で起こされたスレッドはこの状態です。 Thread#join でスレッドの終了を待っているスレッドもスレッドの終了によりこの状態になります。 この状態のスレッドは「生きて」います。

sleep (停止状態)

Thread.stopThread#join により停止されたスレッドはこの状態になります。 この状態のスレッドは「生きて」います。

aborting (終了処理中)

Thread#kill 等で終了されるスレッドは一時的にこの状態になります。この状態から停止状態(sleep)になることもあります。 この状態のスレッドはまだ「生きて」います。

dead (終了状態)

Thread#kill 等で終了したスレッドはこの状態になります。この状態のスレッドはどこからも参照されていなければ GC によりメモリ上からなくなります。 この状態のスレッドは「死んで」います。

デッドロックの検出

ruby はデッドロックを検出します。デッドロックを検出した場合、例外 fatal が発生してプロセスは終了します。デッドロックの条件は以下のとおりです。

メインスレッドだけが Thread.stop で停止している状態は sleep forever と同じと見なし、 fatal は発生しません。