Ruby の新しい演算子候補 / 標準添付ライブラリ 'thwait'
*>
って Ruby の新しい演算子として使えることない? 右側代入とか。同様に +>
とか />
とかも使えそう。
~>
とかもいけそうだけれど、->
とまちがえやすそう。
関係ないけれど、早く Guild 使ってみたいな。笹田さん、がんばって下さい。
Thread の話。いくつかの Thread をまとめて待つのには、
threads = [] 5.times do threads << Thread.new {sleep(rand(0.5..1.0))} end threads.each {|t| t.join}
みたいなやり方はうまくない。動かないことはないけれど、これでは待っている Thread は常に 1つしかなくて、すべてを同時に待っているのではない。これは標準添付ライブラリの 'thwait' というのを使うとうまくいく。
require 'thwait' threads = [] 5.times do threads << Thread.new {p Thread.current; sleep(rand(0.5..1.0))} end ThreadsWait.all_waits(*threads) {|t| p t}
これの結果。
#<Thread:0x00005633007e7b18@a6.rb:5 run> #<Thread:0x00005633007e78e8@a6.rb:5 run> #<Thread:0x00005633007e7a00@a6.rb:5 run> #<Thread:0x00005633007e75f0@a6.rb:5 run> #<Thread:0x00005633007e74d8@a6.rb:5 run> #<Thread:0x00005633007e75f0@a6.rb:5 dead> #<Thread:0x00005633007e7a00@a6.rb:5 dead> #<Thread:0x00005633007e78e8@a6.rb:5 dead> #<Thread:0x00005633007e74d8@a6.rb:5 dead> #<Thread:0x00005633007e7b18@a6.rb:5 dead>
こんな風。これどうやっているのだろうとライブラリのソースを読んでみたら、Thread を待つのにさらに Thread と Thread::Queue を使っていた。なるほどなという感じ。
どうでもいいけれど、ムダに凝ってみた。
require 'thwait' threads = [] 5.times do |i| threads << Thread.new(i) {|i| puts "Thread #{i} start."; sleep(rand(0.5..1.0))} end h = threads.zip([*0..4]).to_h ThreadsWait.all_waits(*threads) {|t| puts "Thread #{h[t]} is dead."}
結果。
Thread 1 start. Thread 0 start. Thread 3 start. Thread 4 start. Thread 2 start. Thread 4 is dead. Thread 2 is dead. Thread 1 is dead. Thread 3 is dead. Thread 0 is dead
スレッドの開始って順番が保証されないのだな。
Thread とか Fiber っておもしろそうで使ってみたいけれど、何に使ったらいいだろう。「ブロック崩し」みたいなゲームとか?