読者です 読者をやめる 読者になる 読者になる

ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

Ruby で複数スレッドの終了を待つために ThreadsWait を使う (複数スレッドのうちのどれかひとつの終了や全てのスレッドの終了)

Ruby

Ruby において Thread の終了を待つための方法について。 id:hitode909 さんの上記ブログ記事を読んで、「そういや複数スレッドに対する join 処理をするための簡単な方法って何かありそうなもんだけど知らないなー」 と思って調べてみました。

単体の Thread オブジェクトに対しては Thread#join メソッド を使うわけですが、複数 Thread オブジェクトに対してどれかひとつが終了するのを待つとか、全部が終了するのを待つとかしたい場合には、標準添付ライブラリの ThreadsWait が使えるみたいです。 このクラスのドキュメントは以下 *1

私も全然知らなかったんですが、ThreadsWait クラスができたのは 15 年も前で、石塚さんが matz さんに提案して lib に取り込まれた模様。

標準添付ライブラリなので require しないと使えません。 ファイル名が thwait.rb なので、require "thwait" とします。

コードサンプル

ひとでさんとこのサンプルコードに近いもの。

require 'open-uri'
require 'nokogiri'
require 'thwait'

threads = []
threads << Thread.new {
  (Nokogiri open 'http://hitode909.hatenablog.com').at('title').content
}
threads << Thread.new {
  (Nokogiri open 'http://hatenablog.com').at('title').content
}

tw = ThreadsWait.new(*threads)
# 最初に終了したスレッドの値を表示
th = tw.next_wait
puts th.value
# 2 番目に終了したスレッドの値を表示
th = tw.next_wait
puts th.value

*1:Ruby 1.9.3 のドキュメントなので、2.0.0 以降のものは探してください。