问题1
检查MRI 1.8.7源代码,没有明显的方法可以让线程处于“停止”状态。
您可以让线程在锁定的互斥量上阻塞,然后在想让线程继续运行时解锁互斥量。
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
问题2(有点)
你知道吗,你可以向线程传递参数吗? 任何传递给Thread.new的东西都会作为块参数传递:
t = Thread.new(1, 2, 3) do |a, b, c|
puts "Thread arguments: #{[a, b, c].inspect}"
end
还有"线程本地变量",即每个线程的键/值存储。使用Thread#[]=
设置值,使用Thread#[]
获取它们。您可以使用字符串或符号作为键。
go = Mutex.new
go.lock
t = Thread.new(1, 2, 3) do |a, b, c|
go.lock
p Thread.current[:foo]
end
t[:foo] = "Foo!"
go.unlock
t.join
问题2,真的吗
你可以按照自己的意愿去做。这是一项艰巨的工作,特别是当处理线程的通常方式如此简单时。你需要权衡利弊:
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
x = Thread.new {etc}
替换掉x.start
? - Brent.Longborough