This article mainly introduces the PHP multi-process Programming example, this article is explained in Linux implementation of PHP multi-process programming, the need for friends can refer to the following
Envy Naruto Naruto's shadow? Yes, the PHP program is able to activate the shadow! Want to complete the task, and feel that a process is too slow, then try a multi-process to do it. This article will cover the basic needs of PHP multi-process, how to create multi-process and basic signal control, and temporarily will not tell you how to communicate between the process and information sharing.
1. Preparation
Before you start, make sure you're not using the m$ Windows platform (because I don't have windows). Linux/bsd/unix should be no problem at all. Make sure the working environment comes up and see if we have all the PHP modules we need. Open terminal and enter the following command:
Copy CodeThe code is as follows:
$ php-m
This command checks and prints all open extensions for the current PHP, and see if Pcntl and POSIX are in the output list.
1.1. Pcntl
If Pcntl is not found, probably is compiled without compiling the extension. If you are the same as me to compile the installation of PHP, then you need to recompile the installation of PHP. Remember to add the--ENABLE-PCNTL parameter when configuring.
Copy CodeThe code is as follows:
$ cd/path/to/php_source_code_dir
$./configure [some other options]--enable-pcntl
$ make && make install
1.2. POSIX
The goods are generally installed by default, as long as you compile the time without adding--disable-posix.
2. Pre-knowledge
Before you continue, you need to know a little bit about Linux multi-processes. What happened to the multi-process? This is a little bit different from Naruto's avatar. First of all, Naruto grew up to large, such as 16-year-old, cough. One day he started his shadow, and he separated 5 of him. Obviously, these are the 16-year-old Naruto, not the newborn baby who will cry without knowing what to do (it's called cloning). Then, the different places come: they become independent people to do their own things, and no longer know what other fen and the original did what (of course, not like the animation in the same accumulation of experience to the original body). Unless they communicate with each other, the only thing that is before the age of 16 is their shared memory.
A classmate said, boss, you don't hang Dad? I didn't see the ninja! Well, you can go and see it again.
Finally, the preparation of knowledge is finished, is a general understanding of the main process to open the child process is what. The code of the child process is exactly the same as the main process, and there is a part of everything that is executed until the shadow is launched.
3. The technique of Shadow
So how can you understand the contents of the scrolls without a bit of basic knowledge? Opening the reel first saw a word: fork.
3.1. Fork
Fork? Forks are forked, one is different! That's almost what it means. Create a child process with this command. You need to use the Pcntl_fork () function here. (You can simply take a look at the PHP manual for an introduction to this function.) ) to create a PHP script:
Copy CodeThe code is as follows:
$pid = Pcntl_fork (); Once the call succeeds, things get a little different.
if ($pid = =-1) {
Die (' fork failed ');
} else if ($pid = = 0) {
} else {
}
The Pcntl_fork () function creates a child process, and the only difference between a child process and a parent process is that the PID (process ID) and PPID (parent process ID) are different. Under Terminal view process with PS command (ask man to see PS How to use: Man PS). When the function returns a value of-1, the fork fails. Try adding a sentence in front of the IF: Echo $pid. Php_eol;. Running your script, the output might look like this (the code for the child process and the parent process is the same):
Copy CodeThe code is as follows:
67789 # This is what the parent process prints
0 # This is a sub-process printed
After the Pcntl_fork () function call succeeds, the PID of the child process is returned in the parent process, and 0 is returned in the child process. Therefore, the following direct with the IF branch to control the parent process and the child process do different things.
3.2. Assigning tasks
Then let's talk about Naruto's 16-year-old avatar, assigning two simple output tasks to the original and the Avatar:
Copy CodeThe code is as follows:
$parentPid = Getmypid (); This is the legendary memory before the age of 16.
$pid = Pcntl_fork (); Once the call succeeds, things get a little different.
if ($pid = =-1) {
Die (' fork failed ');
} else if ($pid = = 0) {
$mypid = Getmypid (); Get the PID of the current process with the Getmypid () function
Echo ' I am child process. My PID is '. $mypid. ' And my father ' PID is '. $parentPid. Php_eol;
} else {
Echo ' Oh my god! I am a Father now! My Child's PID is '. $pid. ' and mine is '. $parentPid. Php_eol;
}
The result of the output might be this:
Copy CodeThe code is as follows:
Oh my god! I am a Father now! My Child's PID is 68066 and mine is 68065
I am child process. My PID is 68066 and my father ' s PID is 68065
Again, after the Pcntl_fork () call succeeds, a program becomes two programs: a program gets the $pid variable value is 0, it is a child process, another program gets a value of $pid greater than 0, this value is the PID of the child process, it is the parent process. In the following branch statement, different code is run because of the $pid value. Again, the code for the child process is the same as the parent process. So it is necessary to assign them different tasks through the branch statement.
3.3. Child Process Recycling
Did you just have man PS? Generally I used PS aux plus grep command to find the running background process. There is a column of stat that identifies the running state of each process. Here, we focus on status Z: Zombies (Zombie). A child process becomes a zombie process when the child process exits before the parent process, and the parent process does not do any processing on it. Oops is not the same as the shadow in the fire shadow. Naruto's Shadow is dead and then automatically disappears, but the child process here is dead and left a shell in it until the parent process reclaims it. Although the zombie process does not account for any memory, but it is very annoying, the yard of a pile of dead zombies all feel strange. (Don't forget that they also occupy the PID)
In general, the dead child process is recycled before the parent process is finished. Inside the pcntl extension there is a pcntl_wait () function that suspends the parent process until a child process exits. If a child process becomes a zombie, it will return immediately. All the sub-processes are recycled, so it's okay to wait!
3.4. The parent process hangs first
What if the parent process hangs first? What's going to happen? Nothing will happen and the child process is still running. But at this point, the subprocess is handed over to process 1th, and process 1th becomes the stepfather of those processes. Process 1th will handle the resources of these processes well, and when they end, process 1th will automatically reclaim resources. So, another temporary way to deal with zombie processes is to close their parent processes.
4. Signal
The general multi-process thing is that the above is over, but the signal is really a very important thing in the system. The signal is the semaphore, light a signal, the program will react. You must have used this, for example, to run a program under the terminal, waiting for a half-day of no response, you may press CTRL + C to close the program. In fact, this is the signal that sends an interrupt to the program via the keyboard: SIGINT. Sometimes the process loses its response and the kill [PID] command is executed, and the program receives a sigterm signal without any other parameters. When the program receives the above two signals, it will end execution by default, so is it possible to change this default behavior? Must be able to ah!
4.1. Registration Signal
People are living procedures are also live, but the program needs to follow the rules of people to run. Now start to reset the rules for the signal, the function used here is pcntl_signal () (Why not check the PHP manual before continuing?). )。 The following procedure will redefine behavior for SIGINT, and be careful:
Copy CodeThe code is as follows:
Defines a processor that only outputs one line of information after receiving the SIGINT signal
function Signalhandler ($signal) {
if ($signal = = SIGINT) {
Echo ' Signal received '. Php_eol;
}
}
Signal registration: When a SIGINT signal is received, the Signalhandler () function is called
Pcntl_signal (SIGINT, ' Signalhandler ');
while (true) {
Sleep (1);
Do something
Pcntl_signal_dispatch (); When a signal is received, the registered Signalhandler () is called
}
Execute it, press CTRL + C at any time to see what happens.
4.2. Signal distribution
Note: the Pcntl_signal () function is simply a sign-up signal and its processing method, the Pcntl_signal_dispatch () function that actually receives the signal and calls its processing method. Try replacing the/do something with the following code:
Copy CodeThe code is as follows:
for ($i = 0; $i < 1000000; $i + +) {
Echo $i. Php_eol;
Usleep (100000);
}
Execute the script under the terminal and try to press CTRL + C while it is outputting the numbers continuously. See what the program is responding to? Well...... Nothing, except the screen may be a ^c, the program has been continuously output numbers. Because the program has not been executed to Pcntl_signal_dispatch (), there is no call to Signalhandler (), so there is no output signal received.
4.3. Version issues
If you carefully read the PHP document, you will find Pcntl_signal_dispatch () This function is more than PHP 5.3 support, if your PHP version is greater than 5.3, it is recommended to use this method to call the signal processor. 5.3 The following should be added before registering the signal: Declare (ticks = 1); indicates that each low-level instruction is executed, the signal is checked once, and if the registered signal is detected, its signal processor is called. It's pretty uncomfortable to think, why have you been checking it all the time? It would be nice to have a look at the place we specified.
4.4. Feel the Zombie process
Now we go back to the issue of child process recycling (almost forgot = = "). When one of your child processes hangs (or ends), the parent process is still running and may not exit for a long time. A zombie process stands up from here! At this point, the umbrella company (the kernel) found a zombie in its site, who is the son of the zombie? Look at the Ppid and you'll know. The kernel then sends a signal to the PPID process (that is, the parent process of the zombie process): SIGCHLD. Then, do you know how to reclaim this subprocess in the parent process? Hint, use the pcntl_wait () function.
4.5. Send a signal
I hope I've just had a serious man over kill command. It actually sends a signal to the process, and in PHP it can also call the Posix_kill () function to achieve the same effect. With it, you can control the operation of other child processes in the parent process. For example, close all child processes before the end of the parent process, then fork in the parent process to record the PID of all child processes, the parent process before the end of a sequence to send the end signal to the child process.
5. Practice
PHP's multi-process and C is quite similar, to understand the future in other languages to write the same thing is similar to the same situation. If you are free, try to write a small program and feel the taste of it:
The 1.16-year-old Naruto sends a shadow, and divides 5 fen.
2. Each clone will live for 10-30 seconds at random and output dots per second.
3. Ensure that the body can feel the end of the clone, and then activate another clone, to ensure that there are up to 5 copies
4. Do not use nohup, so that the original body can still run after the terminal is closed
5. Write the number of copies (5) into a configuration file, and when sending a signal to the original (you can consider using SIGUSR1 or SIGUSR2), the original reads the configuration file and updates the maximum number of allowed clones.
6. If you have more than a few, close a few, if less, and then split out a few
Tips:
1. Use the while loop to keep the process running, pay attention to sleep to avoid 100% CPU usage
2. When the terminal of the running process is closed, the program receives a SIGHUP signal
3. The INI configuration file can be parsed with the Parse_ini_file () function
Source: >
From for notes (Wiz)
PHP Multi-Process Programming example