Your first while loop is a busy-wait loop, which is usually undesirable (definitely undesirable in this case). It would make sense to choose an interval that fits your problem for how often you need to check for $templog, and only poll that often. Even a delay of 1 second would greatly reduce the I/O and CPU load, but if you can live with longer, great.

Better yet is to avoid polling altogether. What creates the file named $templog in the first place? Instead of using a flag file like this, can you use some kind of inter-process communication, or perhaps does it even make sense to just call DB_Update_Stats() at the time? These are questions you'd have to answer yourself, because there isn't enough information about your program here for me to confidently make that determination.

Also, sleeping for 2 hours is risky; you might end up doing DB_Backup() more often than you expect, if your process is restarted or receives a signal. Are you on a system that has a task scheduler like cron or the Windows task scheduler? Those tend to be much more robust than a do-it-yourself solution, plus they only consume resources when they're running, not the 1 hour and 59 minutes in between. Again, you may have good reason to want to do it this way, but it may be worth considering.

Once you've considered the above paragraphs, then you can look at the "how" of combining the two loops. In a case like this, you can decide how often each thing is supposed to happen (checking for $templog, and doing your DB backup), but sleep for a much shorter interval and compare time to see how long it's been. Here's one way you might do that, using a dispatch table (maybe more than you need, but if your needs expand later you'll be glad you know how):

my %tasks = ( templog => { interval => 5, # seconds code => sub { if (-e $templog) { ... } else { ... } }, }, backup => { interval => 2 * 60 * 60, # 2h code => \&DB_Backup, }, ); while (1) { for (keys %tasks) { my $since = time - ($tasks{$_}{last} || time); if ($since >= $tasks{$_}{interval}) { $tasks{$_}{code}->(); $tasks{$_}{last} = time; CheckTS(); # Or put this in each sub { } } } sleep 1; # See note }

Note: With a little algebra, you can calculate the exact length of time to sleep until the next event hits, but in practice, checking a small hash once per second is nothing.

Hopefully this will get you started in the right direction.

use strict; use warnings; omitted for brevity.

In reply to Re: Concurrent Whiles? by rjt
in thread Concurrent Whiles? by dcthehole

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.