咳といいます。

> >   while true
> >     tuple = ts.in([:find, nil, nil])
> >     thread = Thread.new(tuple[2]) { |arg| find_it(arg) }
> >     ts.out([:find_result, tuple[1], DRbObject.new(thread)])
> >     trhead.join
> >   end
> 
> この方法を試しておりまして、上記コード例の"thread.join"を省略しても良さ
> そうに思えるのですが、ここでスレッドの完了を待つ必要というか、理由はどの
> ようなものでしょうか?

理由の一つはGCでもう一つは仕事をするスレッド数などの制御をするためです。



> GCの関係かと思いましたが、TupleSpaceへ投入したスレッドは参照され続けてい
> ることになって、要求側がタプルを取り出すまではGCの対象になりませんよね?

もしかしてTupleSpaceはエンジンと同じプロセスにありますか?
TupleSpaceがちがうプロセスにあると参照されないと思います。


ちなみに、次のコードでなにげなく DRbObject.new(thread)
してます。これはthreadを渡すとタプル全体が参照渡しになって
しまうのでに一つの要素だけDRbObjectにしてます。

> >     ts.out([:find_result, tuple[1], DRbObject.new(thread)])


> 生成したスレッドの終了を待たずに次のタプルを取り出すことで、多数のスレッ
> ドを生成してしまわないようにする仕組みかとも思いましたが、それでは多数の
> 処理要求を受けた際に1つずつ処理することになるような...。そのような負荷の
> 抑制が狙いでしょうか?

そうです。

処理の完了を待たずに要求タプルを取り出してしまうとまだ
検索処理中の遅いマシンにも仕事が振られてしまうのでもっ
たいない感じがします。
なるべく手の空いているマシンに仕事が行くように、このように
しました。

一つのプロセスで上記のループをスレッドにして複数起動することも
できますよね。
そしたら速いマシンにはこのスレッドを3つ動かし、のろいマシン
では1つ動かす、とかしても面白いかも。



> また、find_it内で例外が発生する場合に備えて次のようにする必要があると理
> 解していますが、正しいでしょうか?
> 
>   begin
>     thread.join
>   rescue
>   end

そうですね。rescueした方がよさそうですね。