两个与Ruby线程相关的问题

Geo*_*Geo 8 ruby inheritance multithreading

第一:

  • 如何创建一个不立即启动的Thread.如果我使用initialize没有块,则会引发异常.

  • 我怎样才能将Thread子类化,以便我可以添加一些自定义属性,但保留与基本Thread类相同的功能?我也不想使用这个initialize(&block)方法.

为了更好地说明这一点

对于第一个问题:

x = Thread.new
x.run = {
  # this should happen inside the thread
}
x.start # i want to manually start the thread
Run Code Online (Sandbox Code Playgroud)

对于第二个:

x = MyThread.new
x.my_attribute = some_value
x.run = {
  # this should happen when the thread runs
}
x.start
Run Code Online (Sandbox Code Playgroud)

我正在寻找类似的东西.希望你能帮忙.

Way*_*rad 11

问题1

检查MRI 1.8.7来源显示没有明显的方法来启动处于"停止"状态的线程.

您可以做的是让线程阻塞在锁定的互斥锁上,然后在需要线程时解锁互斥锁.

#!/usr/bin/ruby1.8

go = Mutex.new
go.lock
t = Thread.new do
  puts "Thread waiting to go"
  go.lock
  puts "Thread going"
end
puts "Telling the thread to go"
go.unlock
puts "Waiting for the thread to complete"
t.join

# => Thread waiting to go
# => Telling the thread to go
# => Thread going
# => Waiting for the thread to complete
Run Code Online (Sandbox Code Playgroud)

问题2(排序)

你知道你可以将参数传递给你的线程吗?传递给Thread.new的任何东西都作为块参数传递:

#!/usr/bin/ruby1.8

t = Thread.new(1, 2, 3) do |a, b, c|
  puts "Thread arguments: #{[a, b, c].inspect}"
  # => Thread arguments: [1, 2, 3]
end
Run Code Online (Sandbox Code Playgroud)

还有"线程局部变量",每线程键/值存储.使用Thread#[]=设定值,并Thread#[]给他们回来.您可以使用字符串或符号作为键.

#!/usr/bin/ruby1.8

go = Mutex.new
go.lock
t = Thread.new(1, 2, 3) do |a, b, c|
  go.lock
  p Thread.current[:foo]    # => "Foo!"
end  
t[:foo] = "Foo!"
go.unlock
t.join
Run Code Online (Sandbox Code Playgroud)

问题2,真的

你可以做你想做的事.这是一项很多工作,特别是当处理线程的常用方法非常简单时.你必须权衡加号和减号:

#!/usr/bin/ruby1.8

require 'forwardable'

class MyThread

  extend Forwardable

  def_delegator :@thread, :join
  def_delegator :@thread, :[]=
  def_delegator :@thread, :[]

  def initialize
    @go = Mutex.new
    @go.lock
    @thread = Thread.new do
      @go.lock
      @stufftodo.call
    end
  end

  def run(&block)
    @stufftodo = block
    @go.unlock
    @thread.join
  end

end

t = MyThread.new
t[:foo] = "Foo!"
t.run do
  puts Thread.current[:foo]
end
t.join

# => "Foo!"
Run Code Online (Sandbox Code Playgroud)