PHP multi-process programming Summary (recommended), php process programming Summary
1. Prepare
Before you start, make sure that you are not using the M $ Windows platform (because I do not have Windows ). Linux/BSD/Unix should be okay. After confirming the working environment, let's take a look at whether all the PHP modules we need are available. Open the terminal and enter the following command:
$ Php-m
This command checks and prints all the extensions currently enabled in PHP, and checks whether pcntl and posix are in the output list.
1.1. pcntl
If the pcntl cannot be found, the extension is not compiled during the compilation of octal. If you compile and install PHP like me, you need to re-compile and install PHP. Add the -- enable-pcntl parameter during configuration.
$ cd /path/to/php_source_code_dir $ ./configure [some other options] --enable-pcntl$ make && make install
1.2. posix
This item is usually installed by default, as long as you do not add -- disable-posix during compilation.
2. Prerequisites
Before continuing, you need to have a little understanding of Linux multi-process. What is multi-process? This is a little different from the shadow in Naruto. First, Naruto grows up from a young age, such as 16 years old and coughs. One day, he starts to split the shadow into five. Obviously, these bodies are also 16-year-old Naruto, instead of babies who will cry when they are just born and don't know what they are ). Then, the difference comes: people become independent people to do their own thing, they no longer know what the other bodies and their original bodies have done (of course, they will not accumulate experience as in cartoons ). Unless they communicate with each other, only things before the age of 16 are their memories.
Some people have said, boss. Isn't that difficult? I have never seen Naruto again! You can go and see it again ......
Finally, the preparation is complete, which is to give a general idea of what the sub-processes developed by the main process are. The sub-process code is exactly the same as that of the main process. Another part of the code is to execute all the content until the sub-process is split. For more information, see the operating system course.
3. Shadow Separation
So how can we understand the content in the scroll without basic knowledge? When you open the scroll, you first see the word fork.
3.1. fork
Forks? The fork is a branch. It's more than one! This is basically what it means. Use this command to create a sub-process. The pcntl_fork () function is used here. (Let's take a brief look at the introduction of this function in the PHP manual .) Create a PHP script:
$ Pid = pcntl_fork (); // once the call is successful, things become somewhat different if ($ pid =-1) {die ('fork failed ');} else if ($ pid = 0) {} else {}
The pcntl_fork () function creates a sub-process. The unique difference between the sub-process and the parent process is that the PID (process ID) and PPID (parent process ID) are different. View the ps command of the process in the terminal (ask man to see how to use ps: man ps ). When the return value of the function is-1, the fork fails. Add echo $ pid. PHP_EOL; in front of if ;. Run your script and the output may be like the following (the result shows that the code of the sub-process and the parent process is the same ):
67789 #0 printed by the parent process # printed by the child process
After the pcntl_fork () function is called successfully, the PID of the child process is returned in the parent process, and 0 is returned in the child process. Therefore, the next step is to directly use the if branch to control the parent process and sub-process to do different things.
3.2. assign a task
Then let's talk about the film separation at the age of 16, and assign two simple output tasks to the original and the split:
$ ParentPid = getmypid (); // This is the legendary memory before the age of 16 $ pid = pcntl_fork (); // once the call is successful, things become a little different. if ($ pid =-1) {die ('fork failed');} else if ($ pid = 0) {$ mypid = getmypid (); // use the getmypid () function to obtain the PID echo 'I am child process of the current process. my PID is '. $ mypid. and my father \'s 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 output result may be as follows:
Oh my god! I am a father now! My child's PID is 68066 and mine is 68065I am child process. My PID is 68066 and my father's PID is 68065
After pcntl_fork () is called successfully, a program becomes two programs: the value of $ pid Variable obtained by a program is 0, and it is a sub-process; the value of $ pid obtained by another program is greater than 0. The value is the PID of the child process, which is the parent process. In the following branch statement, different codes are run due to different $ pid values. Again, the sub-process code is the same as that of the parent process. Therefore, we need to assign different tasks to them through branch statements.
3.3. sub-process recycling
Is there man ps just now? In general, I am used to using the ps aux plus grep command to find the running background process. One column of STAT identifies the running status of each process. Here, we are concerned about the status Z: Zombie ). When a child process exits before the parent process does not process it, the child process will become a zombie process. Oops is different from the shadow. The shadow of Naruto disappears automatically after being killed, but the sub-process remains empty until the parent process recycles it. Although the zombie process does not occupy any memory, it is very out of the way. A bunch of dead people in the yard feel strange. (Don't forget they still occupy PID)
Generally, you can recycle the child processes that have crashed before the parent process ends. There is a pcntl_wait () function in the pcntl extension, which suspends the parent process until a child process exits. If a child process becomes a zombie, it will return immediately. All sub-processes need to be recycled, so it's okay to wait a long time!
3.4. The parent process crashes first
What if the parent process crashes first? What will happen? Nothing happens, and the sub-process is still running. However, at this time, sub-processes will be handed over to process 1, and process 1 becomes the stepfather of these sub-processes. Process 1 will handle the resources of these processes well. When they are finished, process 1 will automatically recycle the resources. Therefore, another temporary way to handle zombie processes is to close their parent processes.
4. Signal
Generally, the multi-process is finished, but the signal is indeed a very important thing in the system. A signal is a signal lamp. When a signal lamp is lit, the program will respond. You must have used this. For example, if you have been running a program on a terminal for a long time, you may press Ctrl + C to close the program. In fact, the keyboard sends an interrupt signal to the program: SIGINT. Sometimes the process will execute the kill [PID] command if it loses response. Without any other parameters, the program will receive a SIGTERM signal. When the program receives the above two signals, the execution ends by default. Is it possible to change this default behavior? Yes!
4.1. Registration Signal
A person is a living program and a living program, but the program must follow the rules set by the person to run. Now we 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 program will redefine the behavior of SIGINT. be careful:
// Define a processor. After receiving the SIGINT signal, only one line of information is output. function signalHandler ($ signal) {if ($ signal = SIGINT) {echo 'signal received '. PHP_EOL; }}// signal registration: When the SIGINT signal is received, call the signalHandler () function pcntl_signal (SIGINT, 'signalhandler'); while (true) {sleep (1 ); // do something pcntl_signal_dispatch (); // call the registered signalHandler () when receiving the signal ()}
Run the command and press Ctrl + C at any time to see what will happen.
4.2. Signal Distribution
Note: The pcntl_signal () function is only used to register the signal and its processing method. The pcntl_signal_dispatch () function is used to actually receive the signal and call its processing method. Try to replace // do something with the following code:
for ($i = 0; $i < 1000000; $i++) { echo $i . PHP_EOL; usleep(100000);}
Execute this script on the terminal and try to press Ctrl + C when it keeps outputting numbers. What is the response of the program? Hmm ...... There is nothing. Except the screen may have an extra ^ C, the program keeps outputting numbers. Because the program has not been executed to pcntl_signal_dispatch (), signalHandler () is not called, so signal received Ed is not output.
4.3. Version Problems
If you carefully read the PHP documentation, you will find that the pcntl_signal_dispatch () function is supported by PHP 5.3 or above. If your PHP version is later than 5.3, we recommend that you use this method to call the signal processor. For versions earlier than 5.3, declare (ticks = 1); indicates that every time a low-level command is executed, the signal is checked. If the registered signal is detected, it calls its signal processor. I think it's quite uncomfortable. Why have I been checking it all the time? Check it at the place we specified.
4.4. Feel the zombie Process
Now let's go back to the sub-process recycling issue (almost forgot = "). When a child process crashes (or ends), but the parent process is still running and may not exit for a long time. A zombie process has stood up! At this time, the umbrella company (kernel) found a zombie in its territory. Who is the son of this zombie? Let's take a look at the PPID. Then, the kernel sends a signal to the PPID process (that is, the parent process of the zombie process): SIGCHLD. Then, do you know how to recycle the child process in the parent process? Use the pcntl_wait () function.
4.5. Send signal
I hope there is a serious man who has just passed the kill command. It actually sends a signal to the process. In PHP, you can also call the posix_kill () function to achieve the same effect. With it, you can control the running of other sub-processes in the parent process. For example, if you disable all child processes before the parent process ends, record the PID of all child processes in the fork process, and send an end signal to the child process before the parent process ends.
5. Practice
The multi-process of PHP is quite similar to that of C. It is similar to that of C in other languages. If you are free, try to write a small program:
A 1.16-Year-Old Naruto sends a shadow to split up five parts.
2. Each sub-body will survive for 10 to 30 seconds at random. What are output points per second?
3. Ensure that the original body can feel the end of the separation, and then start another separation, to ensure a maximum of five Separation
4. Do not use nohup, so that the original user can still run after the terminal is closed
5. write the number of parts (5) into a configuration file. When sending a signal to the original body (SIGUSR1 or SIGUSR2 can be considered, read the configuration file from the original body and update the maximum number of allowed sub-bodies
6. If there is more separation, close a few. If there is less, separate several.
Tip:
1. Use the while loop to ensure the process runs. Pay attention to sleep to avoid 100% of CPU usage.
2. When the terminal running the process is closed, the program will receive a SIGHUP Signal
3. You can use the parse_ini_file () function to parse the INI configuration file.
The above PHP multi-process programming Summary (recommended) is all the content shared by the editor. I hope to give you a reference and support for the help house.