【问题标题】:How do I run a method inside of a class with thread from ruby?如何使用来自 ruby​​ 的线程在类中运行方法?
【发布时间】:2023-04-01 00:18:01
【问题描述】:

我有一个类和属性

class Person
  attr_accessor :name
  def say_hello
   puts "person name #{self.name} "
  end
end

现在我想用这个线程执行 say_hello 方法

queue_thread= []
1..100.times do |number|
  person= Person.new
  person.name= number.to_s
   thread_to_run=Thread.new {person.say_hello}
   queue_thread << thread_to_run
end
queue_thread.map {|thread_current| thread_current.join}

你知道怎么做吗?我看了看,问题是线程无法通过对象实例识别变量。

正确的答案应该是控制台中的这个

"person name 1"
"person name 2"
"person name ..."
"person name etc"

【问题讨论】:

  • 你得到了什么?需要注意的是,多个线程同时写入控制台是一种混淆事物的好方法。一个线程应该处理输出。
  • 感谢回答,我又编辑了,需要通过控制台获取人名1、人名2、人名3。你能帮帮我吗?
  • 如果你需要这个顺序,线程会把事情搞砸。你为什么要穿线?您需要以某种方式收集该输出并在显示之前进行排序。

标签: ruby-on-rails ruby multithreading rubygems


【解决方案1】:

此代码的问题是它在调用join 之前触发了多个线程 - 在此期间,由于线程的异步特性,某些线程可能以不正确的顺序调用。

一个选项是在线程被调用时简单地join。这实际上会暂停迭代,直到线程完成,所以你知道它们会保持有序:

100.times do |number|
  person= Person.new
  person.name= number.to_s
  Thread.new {person.say_hello}.join
end

请注意,在这里使用线程确实没有意义,但它至少表明您可以 join 工作。

另一个选项(也不必要地使用线程)是通过将线程调用存储为 lambda 来延迟线程调用。这基本上是同一件事,但允许您将其拆分为两个迭代:

queue_threads= []
1..100.times do |number|
  person= Person.new
  person.name= number.to_s
  thread_lambda = -> { Thread.new {person.say_hello} }
  queue_threads.push(thread_lambda)
end
queue_threads.map {|thread_lambda| thread_lambda.call.join}

另请注意,1..100.times 并没有按照您的想法行事。这与说100.times 是一样的,例如,如果你说99..100.times,99 将被忽略,它将是 100 次迭代,而不仅仅是 1。如果你想迭代一个范围,你可以使用类似99..100.each do |i|

【讨论】:

    猜你喜欢
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多