2

In a rake task running on jruby-1.7.6, I spawn many Threads on demand and store each of the spawned threads:

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

When I exit the rake task, I terminate all the spawned threads. I use signal handlers :

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

Work-around: Thread.list.last[:spawned_threads] has all my spawned threads.

But wait,

THE SAME CODE IN RUBY 1.9.3 WORKS FINE. Thread.current REMAINS THE SAME.

QUESTIONS:

  1. In JRuby, why does Thread.current differ during signal trapping?
  2. Is a separate being thread spawned just to handle signals?

PLUS, in the signal handler(again), when I try to access an already created Redis connection, it stalls indefinitely, returning nothing! [Happens only in JRuby, not sure if related to signal handling.]

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366

1 Answers1

0

I don't think there is any guarantee of what thread your signal handler will happen in. Even in other languages like C with pthreads this kind of thing is complicated.

I also doubt that Ruby mandates a specific thread will receive your signal, it just so happens that the "main" thread is the one that does. That could possibly change in the future.

You should restructure your code so that there is a well-known place that you can send messages to from any thread. This might take the form of a global variable. You will then need to provide appropriate multithreaded protection to that object's methods, as you never know what thread(s) will be calling a method and when.

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366