tags:

views:

77

answers:

3

I have a big perl script (about 650 lines) that parses data off imdb.com, tvrage.com and can get data using last.fm API, and a few other sites. This script uses quite a few Perl modules so it takes a few seconds to load (on an old PC). What are the different ways (including any 'ugly hacks') in which the script can be sent quickly to the background?

I'll start with a few that I know of.

  1. Run the script as script.pl &
  2. Run the script as screen -dmS script.pl
  3. Use fork() inside the script
  4. Use App::Daemon or Proc::Fork

The problem with 3 and 4 is that when the script is large (like 500 to 600 lines) and uses a lot of modules, it takes some time for the process to fork and sent to background. With #1 and #2, they're instantly sent to background so I'm looking for more solutions like these.

Note: I do not need to get any data from the background process. They're writing to file. I also do not need to know if the background process completed its task successfully or not.

+4  A: 

Regarding 3 and 4: Forking really shouldn't take long, unless you're on Windows (where forking is emulated). Personally I would go for something like App::Daemon (or manually do a double fork).

An alternative (if it's available on your platform) is to run it like setsid script.pl

Leon Timmermans
I'm on Linux.Thanks, I never knew about setsid and it seems to be the fastest solution in this case. I think forking just takes slightly longer because the entire script is forked, which is about 600 lines and uses 10+ modules.
somebody
Proc::Daemon is another good helper module -- it will perform the double fork for you.
Ether
+2  A: 

You can speed up 3 and 4 by deferring the loading/compiling of your Perl modules until after you've forked into the background.

When you use a module, Perl loads and compiles it at "compile-time", which happens before the Perl code in your script is executed, and therefore before you go into the background. This can take a while if you have a lot of modules.

You can replace use with require to have the modules loaded at run-time, after you fork.

e.g. if you have

use MyBigModule qw(run);

You can replace it with the following code, placed in the child part of the fork:

require MyBigModule;
MyBigModule->import(qw(run));
rjh
Thanks for the tip. I didn't know that require and use are different. I gave it a test with using require and it still seems a tad slow compared to the previous solution (setsid). I suppose I could use this solution when I need a large forked process to return data.
somebody
A: 

Option 1 is instant in that as soon as you hit the return key, you'll get the pid back to the terminal and that's it, in the bg. Sounds like you'll know how to fg the proc to check how it's going (if it returns anything that is). As far as your question is concerned, I'd use opt as the quickest.

Mark Lewis