2009-06-27 22 views
8

私は何年もC++世界に住んでいました。私はRubyを使い始めました。私はスレッドを作りたいクラスを持っています。 Rubyでは、Threadからクラスを派生させるのは間違っていますか?私が見ている例は、以下のコンセプトを使用しています。Rubyスレッドの派生クラスですか?

Thread.new { <some block> } 

これは間違いでしょうか?

class MyThread < Thread 
    def initialize 
    end 

    def run 
    <main loop> 
    end 

答えて

9

これは実際にドメインモデリングに関する質問だと思います。

デバッグやパフォーマンスの出力を追加するなど、スレッドが動作する方法を拡張/強化したい場合は、何をしているかには何も問題はありません。

アクティブオブジェクトを使用してドメイン内のいくつかの概念をモデル化したいとします。その場合、Rubyの標準的なアプローチは、ドメインモデルを撓ませることなくこれを達成できるので、より優れています。

継承は、実際にはIS_A関係をモデル化するためにのみ使用してください。このための標準のルビコードは、このソリューションをきれいに包みます。

あなたのオブジェクトをアクティブにするには、それはいくつかの方法で

Class MyClass 

... 


    def run 
     while work_to_be_done do 
     some_work 
     end 
    end 

... 

end 


threads = [] 

# start creating active objects by creating an object and assigning 
# a thread to each 

threads << Thread.new { MyClass.new.run } 

threads << Thread.new { MyOtherClass.new.run } 

... do more stuff 

# now we're done just wait for all objects to finish .... 

threads.each { |t| t.join } 


# ok, everyone is done, see starships on fire off the shoulder of etc 
# time to die ... 
+0

Rubyの標準的なアプローチは何ですか? Threadオブジェクトにコードブロックを渡すだけですか? –

+0

はい - Thread.new {do_stuff}は私が見た最も一般的なアプローチです。 –

+0

私の応答をアクティブオブジェクトの例で更新しました –

6

これは以前のことです。ここでThread.newが呼び出されたときに実行されるRubyのメーリングリストのいずれかから、いくつかのサンプルコードです。

class MyThread < Thread 
    def initialize 
    super("purple monkey dishwasher") {|str| puts "She said, '#{str}.'"} 
    end 
end 

あなたのスレッドを実行するためにThread.forkまたはThread.startを呼び出すことを計画している場合、あなたはこのことを認識する必要がありますRuby documentation those methods

"Thread :: newと基本的に同じですが、Threadクラスがサブクラス化されている場合、そのサブクラスでstartを呼び出すと、サブクラスのinitializeメソッドは呼び出されません。

+0

私はC++プログラマが私の中で出ていると思います。 Rubyでコンストラクタからスレッドを実行することはできますか?通常、これはC++では決して行われません。 – nathan

+0

少し奇妙だと私は同意しますが、Rubyが提供する柔軟性を強調しています。これは良いアイデアですか?少し奇妙ですが、それはクラスと言語によって確かに許されており、非常に読みやすいです。他の人はこれが標準的なことではないことを指摘しましたが、私はこれが最悪のものだとは思わないし、これが完璧なアプリケーションがあるかもしれません。 –

+0

+1あなたはJamesに答えます。あなたは質問に答えました。クリスは実際に私がドメインの問題を抱えていることを実感しました。したがって、授与された答えは彼に向かう。 – nathan

0

を新しく作成されたスレッドをキャプチャする必要があり、それは本当にルビーの方法ではないのですが、それはあなたがスレッドを達成しようとしているかに依存します。

まず最初に、ruby 1.8は本当に実際のスレッドを持っていないので、IOバインドされたものには本当に便利です。

一般に、Rubyではスレッドを表現するのではなく、スレッド内でアクションを実行したいので、スレッドを作成する通常のクラスを定義する方が簡単です。

継承のis_a関係

1

、それは問題ないはずのようにそれはそうなるよう「スレッドがサブクラス化されている場合は、」Rubyのドキュメントが言及スレッドです。上書きが初期化されているかどうかを確認してください。

5

私は、このようにカプセル化を行うことを好む:

class Threader 
    def initialize 
    @thread = Thread.new(&method(:thread)) 
    end 

private 

    def thread 
    # Do thready things... 
    end 
end 

をあなたはまた、スレッドのサブクラスに直接これを行うことができます:

class ThreadyThread < Thread 
    def initialize 
    super(&method(:thread)) 
    end 

private 

    def thread 
    # Do thready things... 
    end 
end 
+0

+1このアイデアに感謝します。呼び出し元のスコープがブロックにリークするため、呼び出し元にスレッドのブロックを定義させるのは危険でした。これははるかにクリーンでカプセル化されています。 – Kelvin

+0

これは私が探していたものです。カプセル化され、整理されています。ありがとう! – hbobenicio

関連する問題