NAME
Forks::Super::Job - object representing a background task
VERSION
0.97
SYNOPSIS
use Forks::Super;
$pid = Forks::Super::fork( \%options ); # see Forks::Super
$job = Forks::Super::Job::get($pid);
$job = Forks::Super::Job::getByName($name);
print "Process id of new job is $job\n";
print "Current state is ", $job->state, "\n";
waitpid $job, 0;
print "Exit status was ", $job->status, "\n";
DESCRIPTION
Calls to Forks::Super::fork() that successfully spawn a child process or create a deferred job (see "Deferred processes" in Forks::Super) will cause a Forks::Super::Job instance to be created to track the job's state. In boolean, numeric, or string context, the Job object behaves like the process identifier of the child process. For many uses of fork(), it will not be necessary to query the state of a background job. But access to these objects is provided for users who want to exercise even greater control over their use of background processes.
Calls to Forks::Super::fork() that fail (return undef or small negative numbers) generally do not cause a new Forks::Super::Job instance to be created.
ATTRIBUTES
Use the Forks::Super::Job::get or Forks::Super::Job::getByName methods to obtain a Forks::Super::Job object for examination. The Forks::Super::Job::get method takes a process ID or job ID as an input (a value that may have been returned from a previous call to Forks::Super::fork() and returns a reference to a Forks::Super::Job object, or undef if the process ID or job ID was not associated with any known Job object. The Forks::Super::Job::getByName looks up job objects by the name parameter that may have been passed in the Forks::Super::fork() call.
A Forks::Super::Job object has many attributes, some of which may be of interest to an end-user. Most of these should not be overwritten.
- pid
-
Process ID or job ID. For deferred processes, this will be a unique large negative number (a job ID). For processes that were not deferred, this valud is the process ID of the child process that performed this job's task.
- real_pid
-
The process ID of the child process that performed this job's task. For deferred processes, this value is undefined until the job is launched and the child process is spawned.
- pgid
-
The process group ID of the child process. For deferred processes, this value is undefined until the child process is spawned. It is also undefined for systems that do not implement getpgrp.
- created
-
The time (seconds since the epoch) at which the instance was created.
- start
-
The time at which a child process was created for the job. This value will be undefined until the child process is spawned.
- end
-
The time at which the child process completed and the parent process received a
SIGCHLDsignal for the end of this process. This value will be undefined until the child process is complete. - reaped
-
The time at which a job was reaped via a call to
Forks::Super::wait,Forks::Super::waitpid, orForks::Super::waitall. Will be undefined until the job is reaped. - state
-
A string value indicating the current state of the job. Current allowable values are
DEFERRED-
For jobs that have been put on the job queue and have not started yet.
ACTIVE-
For jobs that have started in a child process and are, to the knowledge of the parent process, still running.
COMPLETE-
For jobs that have completed and caused the parent process to receive a
SIGCHLDsignal, but have not been reaped.The difference between a
COMPLETEjob and aREAPEDjob is whether the job's process identifier has been returned in a call toForks::Super::waitorForks::Super::waitpid(or implicitly returned in a call toForks::Super::waitall). When the process gets reaped, the global variable$?(see "$CHILD_ERROR" in perlvar) will contain the exit status of the process, until the next time a process is reaped. REAPED-
For jobs that have been reaped by a call to
Forks::Super::wait,Forks::Super::waitpid, orForks::Super::waitall. SUSPENDED-
The job has started but it has been suspended (with a
SIGSTOPor other appropriate mechanism for your operating system) and is not currently running. A suspended job will not consume CPU resources but my tie up memory resources. SUSPENDED-DEFERRED-
Job is in the job queue and has not started yet, and also the job has been suspended. A job in the
SUSPENDED-DEFERREDstate can only move out of this state to theSUSPENDEDstate (with aSIGCONTor a "resume" call).
- status
-
The exit status of a job. See CHILD_ERROR in
perlvar. Will be undefined until the job is complete. - style
-
One of the strings
natural,cmd, orsub, indicating whether the initialforkcall returned from the child process or whether the child process was going to run a shell command or invoke a Perl subroutine and then exit. - cmd
-
The shell command to run that was supplied in the
forkcall. - sub
- args
-
The name of or reference to CODE to run and the subroutine arguments that were supplied in the
forkcall. - _on_busy
-
The behavior of this job in the event that the system was too "busy" to enable the job to launch. Will have one of the string values
block,fail, orqueue. - queue_priority
-
If this job was deferred, the relative priority of this job.
- can_launch
-
By default undefined, but could be a CODE reference supplied in the
fork()call. If defined, it is the code that runs when a job is ready to start to determine whether the system is too busy or not. - depend_on
-
If defined, contains a list of process IDs and job IDs that must complete before this job will be allowed to start.
- depend_start
-
If defined, contains a list of process IDs and job IDs that must start before this job will be allowed to start.
- start_after
-
Indicates the earliest time (since the epoch) at which this job may start.
- expiration
-
Indicates the latest time that this job may be allowed to run. Jobs that run past their expiration parameter will be killed.
- os_priority
-
Value supplied to the
forkcall about desired operating system priority for the job. - cpu_affinity
-
Value supplied to the
forkcall about desired CPU's for this process to prefer. - child_stdin
- child_stdout
- child_stderr
-
If the job has been configured for interprocess communication, these attributes correspond to the handles for passing standard input to the child process, and reading standard output and standard error from the child process, respectively.
Note that the standard read/write operations on these filehandles can also be accomplished through the
write_stdin,read_stdout, andread_stderrmethods of this class. Since these methods can adjust their behavior based on the type of IPC channel (file, socket, or pipe) or other idiosyncracies of your operating system (#@$%^&*! Windows), using these methods is preferred to using the filehandles directly.The package level variables
$Forks::Super::CHILD_STDIN{$job}, $Forks::Super::CHILD_STDOUT{$job}, $Forks::Super::CHILD_STDERR{$job}are equivalent to these instance variables.
FUNCTIONS
get
$job = Forks::Super::Job::get($pidOrName)-
Looks up a
Forks::Super::Jobobject by a process ID/job ID or name attribute and returns the job object. Returnsundeffor an unrecognized pid or job name.
getByName
$job = Forks::Super::Job::getByName($name)@jobs = Forks::Super::Job::getByName($name)-
Looks up one or more
Forks::Super::Jobobjects by the or name attribute. In list context, returns all known jobs that have the given name. In scalar context, returns a single job object orundefif no job has the specified name.
count_active_processes
$n = Forks::Super::Job::count_active_processes()-
Returns the current number of active background processes. This includes only
- 1. First generation processes. Not the children and grandchildren of child processes.
- 2. Processes spawned by the
Forks::Supermodule, and not processes that may have been created outside theForks::Superframework, say, by an explicit call toCORE::fork(), a call likesystem("./myTask.sh &"), or a form of Perl'sopenfunction that launches an external command.
count_queued_processes
$n = Forks::Super::Job::count_queued_processes()-
Returns the current number of inactive tasks in the job queue.
METHODS
A Forks::Super::Job object recognizes the following methods. In general, these methods should only be used from the foreground process (the process that spawned the background job).
waitpid
$job->wait( [$timeout] )$job->waitpid( $flags [,$timeout] )-
Convenience method to wait until or test whether the specified job has completed. See Forks::Super::waitpid.
The calls
$job->waitand$job->wait()will block until a job has completed. But$job->wait(0)will callwaitwith a timeout of zero seconds, so it will be equivalent to a call ofwaitpid $job, &WNOHANG.
kill
$job->kill($signal)-
Convenience method to send a signal to a background job. See Forks::Super::kill.
suspend
$job->suspend-
When called on an active job, suspends the background process with
SIGSTOPor other mechanism appropriate for the operating system. Returns a true value if it thinks it succeeded. Unlike aSIGSTOPsignal, also operates on deferred jobs.
resume
$job->resume-
When called on a suspended job (see suspend, above), resumes the background process with
SIGCONTor other mechanism appropriate for the operating system. Returns a true value if it thinks it succeeded. Unlike aSIGCONT, also operates on deferred jobs.
terminate
$job->terminate-
Terminates the job with signals or other mechanism appropriate for the operating system. This method does not return a value.
is_<state>
$job->is_complete-
Indicates whether the job is in the
COMPLETEorREAPEDstate. This method may not return accurate results for daemon processes. $job->is_started-
Indicates whether the job has started in a background process. While return a false value while the job is still in a deferred state. This method may not return accurate results for daemon processes.
$job->is_active-
Indicates whether the specified job is currently running in a background process. This method may not return accurate results for daemon processes.
$job->is_suspended-
Indicates whether the specified job has started but is currently in a suspended state. This method may not return accurate results for daemon processes.
write_stdin
$job->write_stdin(@msg)-
Writes the specified message to the child process's standard input stream, if the child process has been configured to receive input from interprocess communication. Writing to a closed handle or writing to a process that is not configured for IPC will result in a warning.
Using this method may be preferrable to calling
printwith the process'schild_stdinattribute, as thewrite_stdinmethod will take into account the type of IPC channel (file, socket, or pipe) and may alter its behavior because of it. In a near future release, it is hoped that the simpleprintto the child stdin filehandle will do the right thing, using tied filehandles and other Perl magic.
read_stdout
read_stderr
$line = $job->read_stdout()@lines = $job->read_stdout()$line = $job->read_stderr()@lines = $job->read_stderr()-
In scalar context, attempts to read a single line, and in list context, attempts to read all available lines from a child process's standard output or standard error stream.
If there is no available input, and if the
Forks::Supermodule detects that the background job has completed (such that no more input will be created), then the file handle will automatically be closed. In scalar context, these methods will returnundefif there is no input currently available on an inactive process, and""(empty string) if there is no input available on an active process.Reading from a closed handle, or calling these methods on a process that has not been configured for interprocess communication will result in a warning.
getc_stdout
getc_stderr
$char = $job->getc_stdout()$char = $job->getc_stderr()-
Attempts to read a single character from a child process's standard output or standard error stream. See also "read_stdout" and "read_stderr".
close_fh
$job->close_fh([@handle_id])-
Closes IPC filehandles for the specified job. Optional input is one or more values from the set
stdin,stdout,stderr, andallto specify which filehandles to close. If no parameters are provided, the default behavior is to close all configured file handles.The
close_fhmethod may perform certain cleanup operations that are specific to the type and settings of the specified handle, so using this method is preferred to:# not as good as: $job->close_fh('stdin','stderr') close $job->{child_stdin}; close $Forks::Super::CHILD_STDERR{$job};On most systems, open filehandles are a scarce resource and it is a very good practice to close filehandles when the jobs that created them are finished running and you are finished processing input and output on those filehandles.
state
$state = $job->state-
Method to access the job's current state. See "ATTRIBUTES".
status
$status = $job->status-
For completed jobs (i.e., where
$job->is_completereturns a true value), the<status> method returns the job's exit status. See "ATTRIBUTES".
exit_status
$short_status = $job->exit_status($exit_code,$signal,$coredump) = $job->exit_status-
exit_statusis an alternative method to "status" for retrieving the exit value of a background task that may be more intuitive.In scalar context, it returns the exit status of the program (as returned by the wait call), but shifted right by eight bits, so that a program that ends by calling
exit(7)will have anexit_statusof 7, not 7 * 256. If the background process exited on a signal and/or with a core dump, the result of this function is a negative number that indicates the signal that caused the background process failure.In list context,
exit_statusreturns a three element array of the exit value, the signal number, and an indicator of whether the process dumped core.exit_statusreturns nothing if called on a job that has not completed.
toString
$job->toString()$job->toShortString()-
Outputs a string description of the important features of the job.
acquire
$success = $job->acquire($n)$success = $job->acquire($n, $timeout)$success = Forks::Super::Job->acquire($n)$success = Forks::Super::Job->acquire($n, $timeout)-
Attempts to obtain access to a synchronization resource, for jobs that were launched with the
"sync"option. On success, including the case where the process is already in possession of the specified resource, this method returns true. It returns false if the resource cannot be acquired.$nmust be nonnegative and less than the number of synchronization objects created in the originalfork { sync => ... }call. If a$timeoutargument is included, the method will return false if the synchronization resource cannot be obtained in the specified number of seconds. If the$timeoutis not specified, the method will block until the resource can be acquried.The instance method syntax (
$job->acquire(...)) is for use by a parent process, coordinating with the child process (represented by$job). The package indirect syntax (Forks::Super::Job->acquire(...)) is for use by the child process.The
acquireand "release" interface is portable, though the underlying synchronization implementation may be very different on different platforms.
release
$success = $job->release($n)$success = Forks::Super::Job->release($n)-
Releases a synchronization object, allowing another process to acquire it (see "acquire"). Returns true on success, false on failure (for example, if the calling process did not already possess the specified resource).
Parent processes should use the instance method syntax (
$job->release(...)) with the job object for the child process it is trying to coordinate with. The package indirect syntax (Forks::Super::Job->release(...)) is for use by the child process.
acquireAndRelease
$success = $job->acquireAndRelease($n)$success = $job->acquireAndRelease($n, $timeout)$success = Forks::Super::Job->acquireAndRelease($n)$success = Forks::Super::Job->acquireAndRelease($n, $timeout)-
Roughly equivalent to
$success = $job->acquire($n) && $job->release($n)although it may be performed atomically, depending on the implementation.
reuse
$pid = $job->reuse( \%new_opts )-
Creates a new background process by calling
Forks::Super::fork, using all of the existing settings of the currentForks::Super::Jobobject. Additional options may be provided which will override the original settings.Use this method to launch multiple instances of identical or similar jobs.
$job = fork { child_fh => "all", callback => { start => sub { print "I started!" }, finish => sub { print "I finished!" } }, sub => sub { do_something(); do_something_else(); ... # do 100 other things. }, args => [ @the_args ], timeout => 15 }; # Crikey, I'm not typing all that in again. $job2 = $job->reuse { args => [ @new_args ], timeout => 30 };
dispose
$job->dispose()Forks::Super::Job::dispose( @jobs )-
Called on one or more job objects to free up any resources used by a job object. You may call this method on any job where you have finished extracting all of the information that you need from the job. Or to put it another way, you should not call this method on a job if you still wish to access any information about the job. After this method is invoked on a job, any information such as run times, status, and unread input from interprocess communication handles will be lost.
This method will
close any open filehandles associated with the job
attempt to remove temporary files used for interprocess communication with the job
erase all information about the job
remove the job object from the
@ALL_JOBSand%ALL_JOBSvariables.
VARIABLES
@ALL_JOBS, %ALL_JOBS
Any job object created by this module will be added to the list @Forks::Super::Job::ALL_JOBS and to the lookup table %Forks::Super::Job::ALL_JOBS. Within %ALL_JOBS, a specific job object can be accessed by its job id (the numerical value returned from Forks::Super::fork()), its real process id (once the job has started), or its name attribute, if one was passed to the Forks::Super::fork() call. This may be helpful for iterating through all of the jobs your program has created.
my ($longest_job, $longest_time) = (-1, -1);
foreach $job (@Forks::Super::ALL_JOBS) {
if ($job->is_complete) {
$job_time = $job->{end} - $job->{start};
if ($job_time > $longest_time) {
($longest_job, $longest_time) = ($job, $job_time);
}
}
}
print STDERR "The job that took the longest was $job: ${job_time}s\n";
Jobs that have been passed to the "dispose" method are removed from @ALL_JOBS and %ALL_JOBS.
OVERLOADING
A feature of the Forks::Super module is to make it more convenient to access information about a background process by returning a Forks::Super::Job object instead of a simple numerical process id. A Forks::Super::Job object is overloaded to look and behave like a process ID (or job ID) in any numerical context. It can be passed to functions like kill and waitpid (even CORE::kill and CORE::waitpid) that expect to receive a process ID.
if ($job_or_pid != $another_pid) { ... }
kill 'TERM', $job_or_pid;
But you can also access the attributes and methods of the Forks::Super::Job object.
$job_or_pid->{real_pid}
$job_or_pid->suspend
Since v0.51, the <> iteration operator has been overloaded for the Forks::Super::Job package. It can be used to read one line of output from a background job's standard output, and to allow you to treat the background job object syntactically like a readable filehandle.
my $job = fork { cmd => $command };
while (<$job>) {
print "Output from $job: $_\n";
}
Since v0.41, this feature is enabled by default.
Even when overloading is enabled, Forks::Super::fork() still returns a simple scalar value of 0 to the child process (when a value is returned).
SEE ALSO
AUTHOR
Marty O'Brien, <mob@cpan.org>
LICENSE AND COPYRIGHT
Copyright (c) 2009-2018, Marty O'Brien.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.
See http://dev.perl.org/licenses/ for more information.