Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Controlling a Perl Daemon with Signals

by eastcoastcoder (Sexton)
on Aug 05, 2005 at 21:08 UTC ( [id://481372]=perlquestion: print w/replies, xml ) Need Help??

eastcoastcoder has asked for the wisdom of the Perl Monks concerning the following question:

Hi.

I have a Perl mini daemon that I would like to control as follows:

1) The daemon consists of a loop, which loops until either a counter is reached, or a TERM signal is received

2) When either of those happen, it waits till it finishes the current loop, then exits.

Number 2 does not seem to happen

Here is my code:

use constant MAX_ITERATIONS => 1000; use constant MAX_TIME => 600; use warnings; use strict; my $start_time = time; my $iterations = 0; my $exit_requested = 0; my $handling_request = 0; sub sig_handler { $exit_requested = 1; exit(0) if !$handling_request; } $SIG{TERM} = \&sig_handler; init(); while (!$exit_requested && $iterations <= MAX_ITERATIONS && (time - $s +tart_time) < MAX_TIME) { $handling_request = 1; handle_request(); $iterations++; $handling_request = 0; } exit(0);
Why no work?

Replies are listed 'Best First'.
Re: Controlling a Perl Daemon with Signals
by sk (Curate) on Aug 05, 2005 at 21:46 UTC
    You are saying the script is not terminating right after the interrupt is issued?

    I took your code and added a sub that i can test and also changed your TERM to INT so it is easy for me to test

    #!/usr/bin/perl -w use constant MAX_ITERATIONS => 1000000; use constant MAX_TIME => 600; use warnings; use strict; my $start_time = time; my $iterations = 0; my $exit_requested = 0; my $handling_request = 0; sub sig_handler { $exit_requested = 1; print "Caught interrupt\n"; # exit(0) if !$handling_request; } sub handle_request { print ("hi: $iterations\n") if $iterations % 10000 == 0; } $SIG{INT} = \&sig_handler; # init(); while (!$exit_requested && $iterations <= MAX_ITERATIONS && (time - $s +tart_time) < MAX_TIME) { $handling_request = 1; handle_request(); $iterations++; $handling_request = 0; } print ("Exit value: Iteration = $iterations exit_req = $exit_requested +\n");

    Output Here when I run the script and hit ^C while it is running I get this output

    hi: 0 hi: 10000 hi: 20000 hi: 30000 hi: 40000 hi: 50000 hi: 60000 hi: 70000 hi: 80000 hi: 90000 hi: 100000 hi: 110000 hi: 120000 hi: 130000 Caught interrupt Exit value: Iteration = 133660 exit_req = 1
    Seems to suggest that it picked the interrupt and terminated the loop at that point.

    Is this the behavior you want and you don't see that? Are you sure you are sending TERM signals?

    -SK

      Right - I'm not getting that behaviour.

      I am sure I'm sending term (kill -TERM <pid>)

      Another fact: When I do kill -TERM, instead of exiting, the program seems to freeze, except that memory usage climbs indefintely - so it must be in some time of endless loop!

        I modified the code to handle TERM signal and sent TERM from command prompt. It caught correctly and gave me expected results.

        I am guessing this not a web-based prog, if so I am not well-versed to explain why you it is not working for you.

        Regarding the jch341277's reply on TERM signal, I am not sure whether it is applicable to your case. For example, If the program was entering the condition in the  while block, it should execute just one more time and quit as you do not modify  $exit_requested inside the while block. Other cases should terminate next time the while condition is evaluated

        Can you try the sample program which prints "hi" and see if the same problem occurs. If it does it is very strange as it works just fine for me and I don't see any mistakes in your code.

        However if the above sample code works but not your original code then you might have to check your  handle_request() sub.

        -SK

Re: Controlling a Perl Daemon with Signals
by jch341277 (Sexton) on Aug 05, 2005 at 21:49 UTC

    Actually it does work but the TERM interrupts the currently executing statement. Execution of the script starts with the next statement in the code after the signal handler returns.


    If you add the following to your code and run the script using the debugger you'll see what I mean:

    sub handle_request { sleep 13; sleep 14; }

      I should add that I have a few sleep calls in between iterations and the like - could that be causing the problem?
      I don't understand

        I've made some other changes to the code to illustrate what sk and I are talking about.

        use constant MAX_ITERATIONS => 100000; use constant MAX_TIME => 6000; use warnings; use strict; my $start_time = time; my $iterations = 0; my $exit_requested = 0; my $handling_request = 0; sub sig_handler { $exit_requested = 1; print "Caught interrupt\n"; exit(3) if !$handling_request; } $SIG{TERM} = \&sig_handler; #init(); while (!$exit_requested && $iterations <= MAX_ITERATIONS && (time - $s +tart_time) < MAX_TIME) { $handling_request = 1; handle_request(); $iterations++; $handling_request = 0; handlyn(); } exit(0); #sub init { return 1; } sub handle_request { handlyn(); print ("iterations: $iterations\n"); } sub handlyn { print $handling_request ? "" : "NOT ", "handling\n"; sle +ep 3; }

        The handlyn() gives me time to send a kill to the process which I'm running from the perl debugger. I then issue a "c 13" in the debugger and wait for the "NOT handling" to be printed, send a kill and then step into the script using "s". You'll see that when $handling_request == 1, the script will exit from line 15. When $handling_request == 0, the script exits from line 29. Which I think is how you want it?

        The question is - how does your handle_request work? Is it able to deal with being interrupted only to have execution return to some arbitrary line in the subroutine? What I've done here is to control where the interrupt will occur by giving myself time to send the interrupt at that particular line. But, that isn't how signals generally work in the wild...

        Update: corrected link.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://481372]
Approved by talexb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2024-10-13 19:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.