Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Waking threads that do periodic checks

by metafor (Novice)
on Sep 25, 2011 at 05:15 UTC ( [id://927707]=perlquestion: print w/replies, xml ) Need Help??

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

I am attempting to minimize processor use by having a program (which I plan on spawning off as a thread) sleep for 1 hour and wake to do a check of various RSS feeds. I would like to be able to terminate this thread (either from another program or another thread from the same process) cleanly -- that is, I don't wanna just kill the process ID. Is there a way to wake a perl program that's sleeping from another thread or another program? I know it's supposed to wake up when you send it SIGALRM but the perl documentation says that some systems may use alarms for sleep and that it's dangerous. Also, is there another, cleaner, preferred method to accomplish such a task other than using sleep? I'm basically trying to write a background daemon that runs but that I can cleanly tell to exit.

Replies are listed 'Best First'.
Re: Waking threads that do periodic checks
by BrowserUk (Patriarch) on Sep 25, 2011 at 06:17 UTC

    This is easy to do, though I agree there may well be better ways of solving the real problem:

    #! perl -slw use strict; use threads; use threads::shared; my $quit :shared = 0; $SIG{INT} = sub { print 'SIGINT'; $quit = 1; }; async { while( not $quit ) { my $wakeup = time() + 60 * 60; print( $quit ), sleep 1 while not $quit and time() < $wakeup; ## Do the hourly task; } }->detach; sleep 1 while not $quit; __END__ c:\test>junk60 0 0 SIGINT

    The cpu cost of waking once per second is nominal.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Waking threads that do periodic checks
by ikegami (Patriarch) on Sep 25, 2011 at 05:21 UTC

    Wouldn't it be simpler to use cron to run your program every hour?


    Signals will interrupt sleep if you have a signal handler for them.

    my $exit; local $SIG{INT} = local $SIG{TERM} = sub { $exit = 1; }; my $wakeup_time = time + 60*60; for (;;) { if ($exit) { ... exit(0); } my $sleep_dur = $wakeup_time - time; last if $sleep_dur <= 0; sleep($sleep_dur); }
Re: Waking threads that do periodic checks
by Khen1950fx (Canon) on Sep 26, 2011 at 04:29 UTC
    It took some experimenting to find something that consistently worked as expected. This is what worked for me:
    #!/usr/bin/perl use strict; use warnings; use threads; use Thread::Suspend; $|=1; my $TERM = 0; $SIG{'INT'} = $SIG{'TERM'} = sub { $TERM = 1; }; print "To terminate program, hit ctrl-^C\n"; sub start_thread { my @args = @_; print(join(' ', @args,)); } my $thr = threads->create(\&start_thread); $thr->join(); $thr->suspend(); $thr->yield(); sleep (1) until ($TERM); print ("\e[2K\e[?25h\n"); #to restore proper cursor behavior

      What do you think is the point of this code?:

      $thr->suspend(); $thr->yield();

      Given that it is proceed by: $thr->join(); which means that the thread no longer exists by the time the above two lines are executed. In addition, the ->yield() method of the threads module isn't exported by default, and you do not import it.

      Your code is exactly equivalent to:

      #!/usr/bin/perl use strict; use warnings; $|=1; my $TERM = 0; $SIG{'INT'} = $SIG{'TERM'} = sub { $TERM = 1; }; print "To terminate program, hit ctrl-^C\n"; print( join(' ', ()) ); sleep (1) until ($TERM);

      In other words it does exactly nothing useful and is in no way an answer to the OPs question.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-03-28 10:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found