2013-11-20 4 views
2

В задаче рек работают на JRuby-1.7.6, я икра много нитей по требованию и хранить каждый из порожденных нитей:JRuby Rake Task - Thread.current изменения, когда сигнал захвата INT

puts Thread.current # => #<Thread:0x1e95aeb7> 
Thread.current[:spawned_threads] = {} 

# New thread spawned for every new request and stored and 
# Thread.current obviously remains the same: 

puts Thread.current # => #<Thread:0x1e95aeb7> 

thread_object = Thread.new { 
    # code in infinite loop 
} 
Thread.current[:spawned_threads]["thread_#{counter}"] = thread_object 

Когда я выхожу из задачи грабли, я завершаю все порожденные потоки. Я использую обработчик сигналов:

trap('INT') { 
    terminate_threads 
    exit! 
} 

def terminate_threads 
    puts Thread.current     # => #<Thread:0x7604790c> A different thread! 
    puts Thread.current[:spawned_threads] # => nil 

    Thread.current[:spawned_threads].each do |key, thread| # Error!!! 
    thread.terminate    
    end 
end 

обходные: имеет все мои порожденные темы.

Но ждать,

ЖЕ КОД В RUBY 1.9.3 работает отлично. Thread.current ОСТАЕТСЯ ОДНОЙ.

ВОПРОСЫ:

  1. В JRuby, почему Thread.current различаются во сигналов захвата?
  2. Является ли отдельный поток, порожденный только для обработки сигналов?

PLUS, в обработчике сигнала (снова), когда я пытаюсь получить доступ к уже созданному соединению Redis, он останавливается бесконечно, не возвращая ничего! [Случается только в JRuby, не уверен, связано ли это с обработкой сигналов.]

ответ

0

Я не думаю, что есть какая-либо гарантия того, какая нить будет работать с вашим сигнальным обработчиком. Даже на других языках, таких как C with pthreads, такая сложность ,

Я также сомневаюсь, что Ruby мандатов определенный поток получит ваш сигнал, так получилось, что «основная» нить является той, которая делает. Это может измениться в будущем.

Вы должны перестроить свой код, чтобы было известное место, куда вы можете отправлять сообщения из любого потока. Это может принимать форму глобальной переменной. Затем вам необходимо предоставить соответствующую многопоточную защиту методам этого объекта, так как вы никогда не знаете, какие потоки (ы) будут вызывать метод и когда.