Forks::Super

Extensions and convenience methods for managing background processes
Download

Forks::Super Ranking & Summary

Advertisement

  • Rating:
  • License:
  • Perl Artistic License
  • Price:
  • FREE
  • Publisher Name:
  • Marty O'Brien
  • Publisher web site:
  • http://search.cpan.org/~mob/

Forks::Super Tags


Forks::Super Description

Extensions and convenience methods for managing background processes Forks::Super is a Perl module that provides new definitions for the Perl functions fork, wait, and waitpid with richer functionality. The new features are designed to make it more convenient to spawn background processes and more convenient to manage them and to get the most out of your system's resources.SYNOPSIS use Forks::Super; use Forks::Super MAX_PROC = > 5, DEBUG = > 1; # familiar use - parent returns PID >0, child returns zero $pid = fork(); die "fork failed" unless defined $pid; if ($pid > 0) { # parent code } else { # child code } # wait for a child process to finish $w = wait; # blocking wait on any child, $? holds child exit status $w = waitpid $pid, 0; # blocking wait on specific child $w = waitpid $pid, WNOHANG; # non-blocking wait, use with POSIX ':sys_wait_h' $w = waitpid 0, $flag; # wait on any process in current process group waitall; # block until all children are finished # -------------- helpful extensions --------------------- # fork directly to a shell command. Child doesn't return. $pid = fork { cmd = > "./myScript 17 24 $n" }; $pid = fork { exec = > }; # fork directly to a Perl subroutine. Child doesn't return. $pid = fork { sub = > $methodNameOrRef , args = > }; $pid = fork { sub = > \&subroutine, args = > }; $pid = fork { sub = > sub { "anonymous sub" }, args = > ); # put a time limit on the child process $pid = fork { cmd = > $command, timeout = > 30 }; # kill child if not done in 30s $pid = fork { sub = > $subRef , expiration = > 1260000000 }; # complete by 8AM Dec 5, 2009 UTC # obtain standard filehandles for the child process $pid = fork { child_fh = > "in,out,err" }; if ($pid == 0) { # child process sleep 1; $x = < STDIN >; # read from parent's $Forks::Super::CHILD_STDIN{$pid} print rand() > 0.5 ? "Yes\n" : "No\n" if $x eq "Clean your room\n"; sleep 2; $i_can_haz_ice_cream = < STDIN >; if ($i_can_haz_ice_cream !~ /you can have ice cream/ && rand() < 0.5) { print STDERR '@#$&#$*&#$*&',"\n"; } exit 0; } # else parent process $child_stdin = $Forks::Super::CHILD_STDIN{$pid}; print $child_stdin "Clean your room\n"; sleep 2; $child_stdout = $Forks::Super::CHILD_STDOUT{$pid}; $child_response = < $child_stdout >; # -or- = Forks::Super::read_stdout($pid); if ($child_response eq "Yes\n") { print $child_stdin "Good boy. You can have ice cream.\n"; } else { print $child_stdin "Bad boy. No ice cream for you.\n"; sleep 2; $child_err = Forks::Super::read_stderr($pid); # -or- $child_err = readline($Forks::Super::CHILD_STDERR{$pid}); print $child_stdin "And no back talking!\n" if $child_err; } # ---------- manage jobs and system resources --------------- # runs 100 tasks but the fork call blocks when there are already 5 jobs running $Forks::Super::MAX_PROC = 5; $Forks::Super::ON_BUSY = 'block'; for ($i=0; $i< 100; $i++) { $pid = fork { cmd => $task }; } # jobs fail (without blocking) if the system is too busy $Forks::Super::MAX_LOAD = 2.0; $Forks::Super::ON_BUSY = 'fail'; $pid = fork { cmd = > $task }; if ($pid > 0) { print "'$task' is running\n" } elsif ($pid < 0) { print "current CPU load > 2.0 -- didn't start '$task'\n"; } # $Forks::Super::MAX_PROC setting can be overridden. Start job immediately if < 3 jobs running $pid = fork { sub = > 'MyModule::MyMethod', args = > , max_proc = > 3 }; # try to fork no matter how busy the system is $pid = fork { force = > 1, sub = > \&MyMethod, args = > }; # when system is busy, queue jobs. When system is not busy, some jobs on the queue will start. # if job is queued, return value from fork() is a very negative number $Forks::Super::ON_BUSY = 'queue'; $pid = fork { cmd = > $command }; $pid = fork { cmd = > $useless_command, queue_priority = > -5 }; $pid = fork { cmd = > $important_command, queue_priority = > 5 }; $pid = fork { cmd = > $future_job, delay = > 20 } # keep job on queue for at least 20s # assign descriptive names to tasks $pid1 = fork { cmd = > $command, name = > "my task" }; $pid2 = waitpid "my task", 0; # run callbacks at various points of job life-cycle $pid = fork { cmd = > $command, callback = > \&on_complete }; $pid = fork { sub = > $sub, callback => { start = > 'on_start', finish = > \&on_complete, queue = > sub { print "Job $_ queued.\n" } } }; # set up dependency relationships $pid1 = fork { cmd = > $job1 }; $pid2 = fork { cmd = > $job2, depend_on = > $pid1 }; # put on queue until job 1 is complete $pid4 = fork { cmd = > $job4, depend_start = > }; # put on queue until jobs 2,3 have started $pid5 = fork { cmd = > $job5, name = > "group C" }; $pid6 = fork { cmd = > $job6, name = > "group C" }; $pid7 = fork { cmd = > $job7, depend_on = > "group C" }; # wait for jobs 5 & 6 to complete # manage OS settings on jobs -- not available on all systems $pid1 = fork { os_priority = > 10 }; # like nice(1) on Un*x $pid2 = fork { cpu_affinity = > 0x5 }; # background task will prefer CPUs #0 and #2 # job information $state = Forks::Super::state($pid); # 'ACTIVE', 'DEFERRED', 'COMPLETE', 'REAPED' $status = Forks::Super::status($pid); # exit status for completed jobs # --- evaluate long running expressions in the background $result = bg_eval { a_long_running_calculation() }; # sometime later ... print "Result was $$result\n"; @result = bg_qx( "./long_running_command" ); # ... do something else for a while and when you need the output ... print "output of long running command was: @result\n"; Requirements: · Perl


Forks::Super Related Software