Processes
CHAPTER 15: PROCESSES
Process Management
- Creating a new process (fork, exec, system, backquotes)
- Awaiting process completion (wait)
- Terminating a process (exit)
- Pipes (Process Filehandles)
- Signals (kill, %SIG)
- Environment variables (%ENV)
Fork Function
- Creates a new process
- fork
- Returns the Process ID (PID) of the new process to the parent
process. Returns 0 to the child process.
- On failure $! is set to the value of errno
- Uses fork(2)
- The following items are inherited by the new process from the
invoking Perl process:
Standard Input
Standard Output
Standard Error
Current Working Directory
Umask
- Typical use:
$pid = fork;
Exec Function
- Overlays a process with a new program
- exec (LIST)
exec LIST
- If successful, exec does not return. Otherwise, it always
returns False
- On failure $! is set to the value of errno
- Uses execvp(3)
- If the LIST has more than one argument or LIST is an array with
more than one value, execvp(3) is called with the arguments in
LIST
- BUT if LIST is only one scalar argument, the argument is checked
for Bourne shell metacharacters. If there are any Bourne shell
metacharacters, the entire argument is passed to "/bin/sh -c" for
parsing. Thus, any valid Bourne shell command line can be run,
including a command which performs I/O redirection. If there are
NO shell metacharacters, the argument is split into words and
execvp(3) invoked.
- The LIST elements are variable interpolated
- Typical use:
$status = exec ("date"); # No Bourne shell created
$status = exec ("ls -l | wc -l > wc.out");
# Bourne shell created
Exit Function
- Causes program termination
- exit (EXIT_STATUS)
exit EXIT_STATUS
- Terminates the program with an Exit Status set to EXIT_STATUS.
If EXIT_STATUS is omitted, an Exit Status of 0 is used.
- Uses exit(2)
- Typical use:
exit (1);
Wait Function
- Waits for a child process to terminate
- wait
- Returns the Process ID (PID) of the terminated child process or
-1 if there are no child processes
- On failure $! is set to the value of errno
- The Termination Status of the terminated child is returned in
the special variable $?. To get the Exit Status divide this by
256.
- Uses wait(2)
- Typical use:
$status = wait;
Example Program
- Here is an example of a program segment which forks and execs
"ls -l > dir.out":
if (($pid = fork) == 0)
{
exec ("ls -l > dir.out");
print ("Could not exec: errno is $!\n");
exit (1);
}
elsif ($pid > 0)
{
wait;
}
else
{
print ("Could not fork: errno is $!\n");
}
System Function
- Creates a new process, runs a program in it and waits for its
completion
- system (LIST)
system LIST
- Returns the Termination Status of the program. To get the Exit
Status of the program divide the returned value by 256.
- On failure $! is set to the value of errno
- Uses the fork function to create a new process, does an "exec
LIST" in the child process and awaits for the child process to
complete using the wait function
- Uses fork(2) and execvp(3)
- Typical use:
$term_status = system ("date");
$term_status = system ("ls -l | wc -l > wc.out");
$term_status = system ("long_cmd &");
- Note that in the last example, where the process is to be
executed in the background, the return value of the system
function is the termination status of the Bourne shell process
which started the background process. So if this status
indicates success, we know that the Bourne shell successfully
started the process, but we do NOT know if the program actually
executed successfully.
Process Filehandles
- Can also create processes using process filehandles
- open (FILEHANDLE, "|cmd"); # Fork/exec cmd; STDIN of
# cmd is the Read end of
# the pipe. The FILEHANDLE
# is the Write end of the
# pipe.
- open (FILEHANDLE, "cmd|"); # Fork/exec cmd; STDOUT of
# cmd is the Write end of
# the pipe. The FILEHANDLE
# is the Read end of the
# pipe.
- Returns Process ID of child process on success, undef (False)
on failure. Note that failure only occurs if the fork failed.
If the fork succeeded, but the exec failed, the open still
returns the PID of the child. This is a bad situation, since
its looks like the open succeeded (return value is True), but
the child process has actually died. When this happens, Perl
writes an error message to STDERR.
- On failure $! is set to the value of errno
- Uses popen(3)
- Typical use:
open (IN, "who|"); # Launch "who" command.
# Read output of "who"
# with the IN FH
open (OUT, "|wc -l"); # Launch "wc -l" command.
# Write data to "wc -l"
# with the OUT FH
- When a process filehandle is closed, the invoking Perl program
waits until the process exits. To cause the close to return
immediately, send a SIGKILL signal to the process before closing
the process filehandle.
Backquotes
- Can also run any valid Bourne shell command line and wait for
its completion by enclosing a command in backquotes
- Similar to command substitution in the shell
- When used in a scalar context, a single string consisting of
all of the output (including any embedded newlines) from the
command is returned
- When used in an array context, an array of values is returned,
one for each line of output. (Actually, the output is split
using the Input Record Separator, $/, which is "\n" by default.)
- The Termination Status of the command is returned in $?
- On failure $! is set to the value of errno
- Variable interpolation is done on the command
NOTE: Single quotes inside backquotes do NOT prevent variable
interpolation!
- Typical use:
@files = `ls -l`;
- Ex.
foreach ($perms, $links, $owner, $group, $size,
$month, $day, $year_time, $file) (`ls -l`)
{
print ("File $file has $size bytes\n");
}
Signals
- Perl provides minimal support for sending a UNIX signal to a
process and for defining the desired action on receipt of a
signal
- Use the kill function to send (generate) a signal
- Use the special %SIG associative array to define the action for
a signal
Kill Function
- Sends (generates) a signal to one or more processes
- kill (LIST)
kill LIST
- The first element of LIST must be either the number of the signal
to send or the name of the signal (WITHOUT the "SIG" prefix)
enclosed in quotes
- The remaining LIST elements are the Process IDs of the processes
to receive the signal
- Returns the number of processes successfully signaled
- On failure $! is set to the value of errno
- Uses kill(2)
- Typical use:
$cnt = kill (9, $proc1, $proc2);
$cnt = kill ("INT", @daemons);
%SIG Associative Array
- The special %SIG array contains signal actions
- Changing a key-value pair of the %SIG array changes the action
for a signal
- The signal name (again without the "SIG" prefix) is used as a
key into the %SIG array. The signal catching action is the
corresponding value.
- The action can be:
'DEFAULT' Default action
'IGNORE' Ignore signal
'handler' Name of signal-handling function
- Typical use:
$SIG{'INT'} = 'sigint_handler';
- Ex.
sub sigint_handler
{
print ("Caught SIGINT\n");
print ("Better close TMP file and exit!\n");
close (TMP);
exit (1);
}
...
$SIG{'INT'} = 'sigint_handler';
... # Close TMP and exit if
# SIGINT occurs
close (TMP);
$SIG{'INT} = 'DEFAULT';
... # Done with TMP, can take
# normal SIGINT action
Environment Variables
- The special %ENV array contains the current environment variables
for the Perl process
- Changing a key-value pair of the %ENV array changes the the value
of an environment variable
- The name of the environment variable is used as a key into the
%ENV array. The value of the environmental variable is the
corresponding value.
- Ex.
Here is a simple printenv program:
#!/usr/bin/perl
for $var (sort keys %ENV)
{
print ("$var=$ENV{$var}\n");
}
Special Variables
$? Termination Status of the last process
started by backquotes, started by the
system function or completed due to the
closing of a process filehandle
$$ The Process ID of the current Perl program
(useful for generating temporary filenames)
%SIG Signal action associative array
%ENV Environment variables associative array
Other Process Management Functions
- alarm (SECS)
alarm SECS : causes the alarm signal (SIGALRM) to be sent
in SECS seconds
- getpgrp (PID)
getpgrp PID : returns the Process Group ID of the process
whose PID is specified (returns PGID of
current process if PID is 0)
- getppid : returns the Process ID of the parent process
- getpriority (WHICH, WHO)
: returns the current priority of a process,
process group or user
- setpgrp (PID, PGID)
: sets the Process Group ID of the process
whose PID is specified (sets the PGID of
current process if PID is 0)
- setpriority (WHICH, WHO, PRIORITY)
: sets the current priority of a process,
process group or user
- sleep (EXPR)
sleep EXPR
sleep : causes the Perl script to sleep for EXPR
seconds
- times : returns a four-element array with the user
and system CPU times (in seconds) for the
process and its children
- waitpid (PID, FLAGS)
: waits for a specific process to terminate
Bob Tarr
University of Maryland, Baltimore County
tarr@umbc.edu