Производный класс для Ruby Thread? - PullRequest
8 голосов
/ 27 июня 2009

Я много лет жил в мире C ++ и только начинаю с Ruby. У меня есть класс, который я хотел бы сделать поток. В Ruby неправильно ли выводить класс из Thread? Примеры, которые я вижу, используют концепцию ниже.

Thread.new { <some block> }

Было бы неправильно делать это?

class MyThread < Thread
  def initialize
  end

  def run
    <main loop>
  end

Ответы [ 5 ]

10 голосов
/ 27 июня 2009

Я думаю, что это действительно вопрос моделирования предметной области.

Не было бы ничего плохого в том, что вы делаете, если вы хотите расширить / улучшить поведение потока - например, добавить отладку или вывод производительности, но я не думаю, что вы этого хотите.

Возможно, вы хотите смоделировать концепцию в вашем домене с помощью активных объектов. В этом случае стандартный подход 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 ...
6 голосов
/ 27 июня 2009

Это прекрасно, я видел, как люди делали это раньше. Вот пример кода из одного из списков рассылки Ruby, который запускается при вызове Thread.new:

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

Если вы планируете вызывать Thread.fork или Thread.start для запуска вашего потока, вы должны знать об этом из Ruby документации по этим методам :

"По сути, то же самое, что и Thread :: new. Однако, если класс Thread находится в подклассе, то вызов start в этом подклассе не вызовет метод инициализации подкласса."

5 голосов
/ 19 марта 2012

Я предпочитаю делать инкапсуляцию таким образом:

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

private

  def thread
    # Do thready things...
  end
end

Вы также можете сделать это напрямую для подкласса Thread:

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

private

  def thread
    # Do thready things...
  end
end
1 голос
/ 27 июня 2009

В документации по Ruby для потоков упоминается "Если поток имеет подклассы", поэтому, похоже, все должно быть в порядке. Убедитесь, что при инициализации перезаписи вы звоните super!

0 голосов
/ 27 июня 2009

Это не совсем рубиновый способ, но это зависит от того, чего вы пытаетесь достичь с помощью потока.

Во-первых, ruby ​​1.8 не имеет реальных потоков, поэтому они действительно полезны только для вещей, связанных с IO.

Обычно в ruby ​​вы хотите, чтобы что-то выполняло действие в потоке, а не представляло поток, поэтому проще определить обычный класс, который создает потоки внутри для обработки аспекта потоков.

Наследование - это отношение IS_A

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...