Вопрос 1
Исследование источника МРТ 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
Вопрос 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
Есть также «нить локальные переменные,» а за нить ключ/значение магазина. Используйте 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
Вопрос 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!"
Почему вы не можете просто заменить «x.start» на 'x = Thread.new {etc}'? –