One of the Perl multi-process combat

Source: Internet
Author: User
Tags posix sleep
Perl as an explanatory language, is very popular with the system administrators, the benefits of not much to say, the disadvantages of many, such as the support of the thread has been not good, so most of the time, we need a number of processes to help us complete the work, gossip less, on the code. #!/usr/bin/perl
# test_proc.pl
# Test Multi Process
# Create by lianming:2009-08-12 use strict;
Use warnings; # = = Fork a new process = =
My $pid = fork (); if (!defined ($pid)) {
Print "Error in fork: $!";
Exit 1;
if ($pid = = 0) {# = = Child Proc = =
print "Child:my pid = $$\n";
Sleep (5);
print "child:end\n";
Exit 0;
} else {# = = Parent Proc = =
Print "Parent my pid = $$, and My child ' s PID = $pid \ n";
Sleep (5);
print "parent:end\n";
} exit 0; The execution results are as follows: child:my PID = 19481
Parent my pid = 19480, and My child ' s PID = 19481 (5 seconds Wait)
Child:end
Parent:end the parent process to derive a child process, which requires a command, that is, the return value of the Fork,fork function is assigned to a variable, the above example is assigned to the "$pid", Next, according to the $pid value of different, to divide three kinds of circumstances.     1, fork failure situation: this time, $pid in an undefined state, in the example of an "if (!defined ($pid)" judgment, if true, stating that $pid is undefined, fork failure, this time to print the error message, and exit.     2, sub-process: If it is a sub-process, then the value of $pid is 0, that is, the above example "if ($pid = = 0)" condition is true, in the "$pid = = 0", it is a sub-process, the above example, the child process will own PID out, for 19481.       3, parent process: if it is the parent process, then the value of the $pid is derived from the child process PID, that is, not 0, or else, the case of the above example, the $pid out, you can see, is also 19481, is the PID value of the child process. This is just one of the simplest examples, a parent process that derives a child process, and a little more complex, a parent process that derives multiple child processes with the following code: #!/usr/bin/perl
# test_proc_1.pl
# Test Multi Process
# Create by lianming:2009-08-12 use strict;
Use warnings;
for (my $i = 0; $i < $i + +) {
# = = Fork a new process = =
My $pid = fork (); if (!defined ($pid)) {
Print "Error in fork: $!";
Exit 1;
if ($pid = = 0) {# = = Child Proc = =
Print "Child $i: My pid = $$\n";
Sleep (5);
Print "Child $i: end\n";
Exit 0;
}
Sleep (1);
} exit 0;     This example is, the parent process executes a loop, each time the loop is fork a child process, the child process after the execution of the exit, each cycle waits 1s, loop 10 times. The execution results are as follows: Child 0:my PID = 20499
Child 1:my pid = 20500
Child 2:my pid = 20501
Child 3:my pid = 20502
Child 4:my pid = 20503
Child 0:end
Child 5:my pid = 20506
Child 1:end
Child 6:my pid = 20507
Child 2:end
Child 7:my pid = 20508
Child 3:end
Child 8:my pid = 20509
Child 4:end
Child 9:my pid = 20510
Child 5:end [Root@localhost/tmp]
# Child 6:end
Child 7:end
Child 8:end
Child 9:end Each sub-process takes 5s, then the total required for execution is 15s. However, such code can cause a problem, in the process of execution, you can enter PS AUXF on the other TTY to view the current process status, you will find something like this: root 20531 0.0 0.0 8460 1704 PTS/2 s+ 21:4 6 0:00 \_ Perl test_proc_1.pl
Root 20532 0.0 0.0 0 0 pts/2 z+ 21:46 0:00 \_ [Perl]
Root 20535 0.0 0.0 0 0 pts/2 z+ 21:46 0:00 \_ [Perl]
Root 20536 0.0 0.0 0 0 pts/2 z+ 21:46 0:00 \_ [Perl]
Root 20539 0.0 0.0 0 0 pts/2 z+ 21:46 0:00 \_ [Perl]
Root 20541 0.0 0.0 8460 720 PTS/2 s+ 21:46 0:00 \_ perl test_proc_1.pl
Root 20543 0.0 0.0 8460 720 PTS/2 s+ 21:46 0:00 \_ perl test_proc_1.pl
Root 20545 0.0 0.0 8460 720 PTS/2 s+ 21:46 0:00 \_ perl test_proc_1.pl
Root 20546 0.0 0.0 8460 720 PTS/2 s+ 21:46 0:00 \_ perl test_proc_1.pl
Root 20548 0.0 0.0 8460 720 PTS/2 s+ 21:46 0:00 \_ perl test_proc_1.pl has 4 processes with a status of Z, meaning zombies     process, and the normal program, is that the zombie process should not appear. Under normal circumstances, the child process exits need to do two things, first, the child process exit, send a signal to their parent process, second, the parent process to reclaim the child process, if the parent process is no longer exist, the process will be init, that is, the first process of Linux as its own parent process,     Init will reclaim the child process in place of its parent process.     Our situation is that the child process has called exit, but the parent process does not recycle it, and if the parent process continues to fork the child process, the zombie process will be more and more, more and more, and eventually what will result, I will not say. The parent process has two functions that recycle the child process: Wait, and the waitpid wait function is simpler, without any arguments, after the call, the parent process stops, and then waits for the child process to return. If there are no child processes, return 1 waitpid has two parameters, the first parameter is the PID value of the subprocess to wait, and the other is flag, in general, the first parameter is-1, meaning to wait for all child processes. The calling method is as follows: $procid = fork ();
if ($procid = = 0) {
# = = Child Process = =
Print ("This is printed first\n");
Exit (0);
} else {
# = = Parent Process = =
Waitpid ($procid, 0);
Print ("This is printed last\n");
In fact, the main thing is to let the parent process know when it is necessary to reclaim the child process that has exited, because the parent process also has a lot of work to be busy. This can be achieved by the signal, the child process at the time of exiting, will send a signal to the parent process, as long as we capture this signal, we know that some sub-processes need to be recycled. Examples are as follows: #!/usr/bin/perl
# test_proc_2.pl
# Test Multi Process
# Create by lianming:2009-08-12 use strict;
Use warnings;
Use POSIX ": Sys_wait_h"; # = = Number of zombies proc = =
my $zombies = 0;   My $collect; # = = Get the child signal = =
$SIG {CHLD} = sub {$zombies + +};
for (my $i = 0; $i < $i + +) {
# = = Fork a new process = =
My $pid = fork (); if (!defined ($pid)) {
Print "Error in fork: $!";
Exit 1;
if ($pid = = 0) {# = = Child Proc = =
Print "Child $i: My pid = $$\n";
Sleep (5);
Print "Child $i: end\n";
Exit 0;
} # = = if need to collect zombies = =
if ($zombies > 0) {
while (($collect = Waitpid ( -1, Wnohang)) > 0) {
$zombies--;
}
}
Sleep (1);
} exit 0; The execution results are the same as before: child 0:my pid = 21552
Child 1:my pid = 21553
Child 2:my pid = 21554
Child 3:my pid = 21555
Child 4:my pid = 21556
Child 0:end
Child 5:my pid = 21558
Child 1:end
Child 6:my pid = 21570
Child 2:end
Child 7:my pid = 21572
Child 3:end
Child 8:my pid = 21574
Child 4:end
Child 9:my pid = 21575
Child 5:end [Root@localhost/tmp]
# Child 6:end
Child 7:end
Child 8:end
Child 9:end But the result of PS auxf is very different: root 21551 0.1 0.0 8280 2672 pts/2 s+ 22:06 0:00 \_ perl test_proc_2.pl
Root 21558 0.0 0.0 8280 1168 PTS/2 s+ 22:07 0:00 \_ perl test_proc_2.pl
Root 21570 0.0 0.0 8280 1168 PTS/2 s+ 22:07 0:00 \_ perl test_proc_2.pl
Root 21572 0.0 0.0 8280 1168 PTS/2 s+ 22:07 0:00 \_ perl test_proc_2.pl
Root 21574 0.0 0.0 8280 1168 PTS/2 s+ 22:07 0:00 \_ perl test_proc_2.pl
Root 21575 0.0 0.0 8280 1168 PTS/2 s+ 22:07 0:00 \_ perl test_proc_2.pl The zombie process will not exist. $SIG {CHLD} = sub {$zombies + +};     This statement, in fact, captures the child process exit, the signal sent to the parent process, after capturing, give a variable ($zombies) plus 1. If the "$zombies" is not 0, it means that there is a child process exited, need to be recycled, the parent process called the Waidpid function, a collection, each recycling a child process, the variable minus 1, so that when the "$zombies" minus 0, It means that all zombie processes have been recycled.       Bingo Sometimes, we just carry out a certain amount of tasks, but fork on it, but at some point, we have too many tasks to execute, to continue to fork a lot of sub-processes, but we want to control the number of processes in a range, for example, I a task, I need to have 100 sub-processes to execute, But I can not 100 process all fork out, this is too resource-intensive, so I want to control the number of processes within 10, when the first process exits, I fork the 11th process, the example is as follows: #!/usr/bin/perl
# test_proc_3.pl
# Test Multi Process
# Create by lianming:2009-08-12 use strict;
Use warnings;
Use POSIX ": Sys_wait_h"; # = = Number of proc = =
My $num _proc = 0; # = = Number of collected = =
My $num _collect = 0;   My $collect; # = = Get the child signal = =
$SIG {CHLD} = sub {$num _proc--}; for (my $i = 0; $i < $i + +) {# = = Fork a new process = =
My $pid = fork (); if (!defined ($pid)) {
Print "Error in fork: $!";
Exit 1;
if ($pid = = 0) {# = = Child Proc = =
Print "Child $i: My pid = $$\n";
Sleep (5);
Print "Child $i: end\n";
Exit 0;
} $num _proc + +; # = = if need to collect zombies = =
if (($i-$num _proc-$num _collect) > 0) {
while (($collect = Waitpid ( -1, Wnohang)) > 0) {
$num _collect + +;
}
}
do {
Sleep (1);
} until ($num _proc < 3);
} exit 0; The execution results are as follows: Child 0:my PID = 22641
Child 1:my pid = 22642
Child 2:my pid = 22643
Child 0:end
Child 3:my pid = 22645
Child 1:end
Child 4:my pid = 22647
Child 2:end
Child 5:my pid = 22658
Child 3:end
Child 6:my pid = 22660
Child 4:end
Child 7:my pid = 22661
Child 5:end
Child 8:my pid = 22663
Child 6:end
Child 9:my pid = 22664
Child 7:end [Root@localhost/tmp]
# Child 8:end
Child 9:end Also, see the output of PS auxf as follows: Root 22640 0.0 0.0 8116 2672 pts/2 s+ 22:28 0:00 \_ perl test_proc_3.pl
Root 22660 0.0 0.0 0 0 pts/2 z+ 22:29 0:00 \_ [Perl]
Root 22661 0.0 0.0 8116 1168 PTS/2 s+ 22:29 0:00 \_ perl test_proc_3.pl
Root 22663 0.0 0.0 8116 1168 PTS/2 s+ 22:29 0:00 \_ perl test_proc_3.pl
root     22664  0.0  0.0  8116 1168 pts/2    S+   22:29& nbsp;  0:00              \_ Perl test_proc_ 3.pl        The first subprocess requires 5s to exit, and if 1s executes a fork, there should be 5 sub-processes at the same time, but in this case there are only three, that is to say, to achieve the control of the number of processes.      in this example, several variables are defined:      $num _proc: The number of processes that are active, within 3, so that after the parent process ends each fork, Will check this variable, if it exceeds 3, wait a moment. When the parent process fork The new subprocess, this number increases, and when the child process exits, the parent process captures the signal, and the number is reduced.      $num _collect: The number of processes that have been recycled, one for each child process, and one for the variable.      $i: The number of processes that have been forked.        $num _proc and $num_collect and should be equal to $i, if not equal, that means that there are sub-processes need to be recycled. The control of        process is fairly simple.      sometimes, processes and processes need to communicate, the process is not like a thread, the entire memory space is shared, but Linux also provides a variety of ways to communicate between processes, the simplest way is to exist in the file, The next document discusses a method for storing files.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.