Perl Process Management
In Perl, you can create processes using various methods.
This tutorial will discuss some methods for managing processes.
-
You can use the special variable $$ or $PROCESS_ID to get the process ID.
-
The %ENV hash stores environment variables from the parent process, which is the shell, and these variables can be modified in Perl.
-
exit() is typically used to exit a child process, with the main process exiting after all child processes have exited.
-
All open handles are duplicated with the dup() function in the child process, and closing all handles of a process does not affect other processes.
Backtick Operator
The backtick operator makes it easy to execute Unix commands. You can insert simple commands within backticks. The command execution will return the result:
#!/usr/bin/perl
@files = `ls -l`;
foreach $file (@files){
print $file;
}
1;
Executing the above program will produce the following output:
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root 574 Sep 17 15:16 index.htm
drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root 71 Sep 17 15:16 test.pl
……
system() Function
You can also use the system() function to execute Unix commands, which will directly output the result. By default, it sends output to the current Perl STDOUT, typically the screen. You can also use the redirection operator > to output to a specified file:
Executing the above program will produce the following output:
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root 574 Sep 17 15:16 index.htm
drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root 71 Sep 17 15:16 test.pl
……
You need to be aware of the output results when the command includes environment variables like $PATH or $HOME, as shown below:
Example
#!/usr/bin/perl
$PATH = "I am a Perl variable";
system('echo $PATH'); # $PATH as a shell environment variable
system("echo $PATH"); # $PATH as a Perl variable
system("echo \$PATH"); # Escaped $
1;
Executing the above program will produce the following output:
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
I am a Perl variable
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
fork() Function
The Perl fork() function is used to create a new process.
It returns the child process's PID in the parent process and 0 in the child process. If an error occurs (e.g., insufficient memory), it returns undef and sets $! to the corresponding error message.
fork can be used in conjunction with exec. The exec function terminates the process after executing the command within quotes.
Example
#!/usr/bin/perl
if(!defined($pid = fork())) {
# fork returns undef on error
die "Cannot create child process: $!";
}elsif ($pid == 0) {
print "Output from child process\n";
exec("date") || die "Cannot output date: $!";
} else {
# In the parent process
print "Output from parent process\n";
$ret = waitpid($pid, 0);
print "Completed process ID: $ret\n";
}
1;
Executing the above program will produce the following output:
Output from parent process
Output from child process
Sun Jun 19 22:21:14 2016 CST
Completed process ID: 47117
When a process exits, it sends a CHLD signal to the parent process and becomes a zombie process, which needs to be terminated by the parent process using wait or waitpid. Alternatively, you can set $SIG{CHLD} to IGNORE:
Example
#!/usr/bin/perl
1;
local $SIG{CHLD} = "IGNORE";
if (!defined($pid = fork())) {
# fork error returns undef
die "Unable to create child process: $!";
} elsif ($pid == 0) {
print "Output from child process\n";
exec("date") || die "Unable to print date: $!";
} else {
# In the parent process
print "Output from parent process\n";
$ret = waitpid($pid, 0);
print "Completed process ID: $ret\n";
}
1;
Executing the above program, the output is as follows:
Output from parent process
Output from child process
Sun Jun 19 22:30:56 CST 2016
Completed process ID: -1
Kill Function
Perl kill('signal', (Process List)) sends a signal to a group of processes. The signal is the numeric signal sent, with 9 being to kill the process.
First, let's look at the common signals in Linux, as shown in the following list:
Signal Name Value Annotation Explanation
————————————————————————————————————————————————————————————
HUP 1 A Hangup detected
INT 2 A Interrupt from keyboard
QUIT 3 A Stop from keyboard
ILL 4 A Illegal instruction
ABRT 6 C Abort signal
FPE 8 C Floating-point exception
KILL 9 AF Terminate signal
USR1 10 A User-defined signal 1
SEGV 11 C Invalid memory access
USR2 12 A User-defined signal 2
PIPE 13 A Write to a pipe with no readers
ALRM 14 A Timer signal from alarm
TERM 15 A Terminate signal
CHLD 17 B Child process terminated
CONT 18 E Continue if stopped
STOP 19 DF Stop the process
TSTP 20 D Stop typed at terminal
TTIN 21 D Terminal input for background process
TTOU 22 D Terminal output for background process
The following example sends a SIGINT signal to processes 104 and 102:
Example
#!/usr/bin/perl
kill('INT', 104, 102);
1;