Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Concurrent Whiles?

by rjt (Curate)
on Sep 08, 2013 at 03:24 UTC ( [id://1052864]=note: print w/replies, xml ) Need Help??


in reply to Concurrent Whiles?

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.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2024-04-26 06:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found