1

I am trying to understand how signal handlers attach to a process and their scope for a process.

class Main
  Signal.trap('USR1') do
      Process2.kill
  end
  def main_process
      #do something
      p = Process2.new
      output = p.give_output
      #then again do something
  end
end

class Process2
  Signal.trap('USR1') do
      Process2.kill
  end
  def self.kill
      if @@static_object.blank?
        #do nothing
      else
        #do something
      end
  end
  def give_output
     #do something
     @@static_object = true
     #do something
  end
end

Now if I issue a SIGUSR1 to the process while give_output is getting executed and @@static_object is not nil, the handler should behave as expected. However, even after give_output has finished execution, if a signal is sent, the handler inside Process2 will catch it. From what I understand, the handler gets attached to the process. Can we have two signal handlers for the same process for the same signal? For example - while give_output is executing and a signal is issued, the handler inside Process2 should get control otherwise another signal handler defined in Main should get control.

Anthony E
  • 11,072
  • 2
  • 24
  • 44

2 Answers2

0

I was curious about this myself and came across the following resources: http://timuruski.net/blog/2014/signals-traps-and-rescues/, https://www.ruby-forum.com/topic/87221, and http://www.ibm.com/developerworks/library/l-reent/. That second link has some resources which seem very relevant to your question.

In short, you can only reliably trap one interrupt type per process. Signal interrupts are handled by the host OS. As its name suggests, interrupts halt the normal execution of your program until the interrupt is handled.

Anthony E
  • 11,072
  • 2
  • 24
  • 44
  • Thanks @Anthony E, the links were really useful :). Though I find the first link more useful, it's more similar to what I am trying to do. The second link (a very interesting question!) deals with handling signals while the signal handling block is executed. I want to have two signal handlers for the same process at different places. –  May 05 '16 at 09:18
0

Summarizing the information given in the links posted by @Anthony E. Using signal trap it's not possible to trap a signal from multiple places in your code. If you want to handle signals differently at multiple places, use rescue blocks.

Signal Trap -

 Signal.trap("USR1") do
    #do something
 end

Rescue Interrupt -

  begin
    #some functions
  rescue Interrupt
    #handle the exception
    exit
  end

Difference in the way signals are handled by rescue and trap -

Trap defines the handler at the top of the code, if a signal is triggered, it would be caught by the trap. On the other hand, rescue is defined at the bottom of the code, that is when there is no trap available, it will raise a Signal Exception which will be caught by the rescue block

The signal trap code gets associated with the process and cannot be replaced. If one wants to handle signals at different places of the program in a different way, the best way is to raise an exception and handle it