[Php] // ensure the maximum number of sub-processes if ($ this-& gt; _ maxFork & gt; 0 & amp; $ this-& gt; _ children & gt; $ this-& gt; _ maxFork) {Yii: log (& quot; _ children & gt; & quot ;. $ this-& gt; _ maxFork, CL
[Php]
// Ensure the maximum number of sub-processes
If ($ this-> _ maxFork> 0 & $ this-> _ children> $ this-> _ maxFork)
{
Yii: log ("_ children>". $ this-> _ maxFork, CLogger: LEVEL_WARNING ,__ METHOD __);
$ This-> handler (SIGCHLD );
Usleep (200 );
Continue;
}
/**
* Monitoring signal
* @ Param object socket $ clientt
* @ Return boolean
*/
Public function handler ($ signo ){
Yii: log ("handler {$ signo}", CLogger: LEVEL_INFO, _ METHOD __);
Switch (intval ($ signo )){
Case SIGCLD:
Case SIGCHLD:
Yii: log ("SIGCHLD sub proccess", CLogger: LEVEL_TRACE, _ METHOD __);
// Exit normally
// Declare = 1, that means one signal may be correspond multi-process die
While ($ pid = pcntl_wait ($ status, WNOHANG | WUNTRACED)> 0 ){
If (FALSE === pcntl_wifexited ($ status )){
Yii: log ("sub proccess {$ pid} exited unormally with code {$ status}", CLogger: LEVEL_WARNING, _ METHOD __);
} Else {
Yii: log ("sub proccess {$ pid} exited normally", CLogger: LEVEL_INFO, _ METHOD __);
}
$ This-> _ children --;
}
Break;
Case SIGINT:
Case SIGQUIT:
Case SIGHUP:
// Exit unexpectedly
$ This-> _ cleanup ();
Exit (0 );
Break;
Default:
Break;
}
}
// Ensure the maximum number of sub-processes
If ($ this-> _ maxFork> 0 & $ this-> _ children> $ this-> _ maxFork)
{
Yii: log ("_ children>". $ this-> _ maxFork, CLogger: LEVEL_WARNING ,__ METHOD __);
$ This-> handler (SIGCHLD );
// Usleep (200 );
Continue;
}
/**
* Monitoring signal
* @ Param object socket $ clientt
* @ Return boolean
*/
Public function handler ($ signo ){
Yii: log ("handler {$ signo}", CLogger: LEVEL_INFO, _ METHOD __);
Switch (intval ($ signo )){
Case SIGCLD:
Case SIGCHLD:
Yii: log ("SIGCHLD sub proccess", CLogger: LEVEL_TRACE, _ METHOD __);
// Exit normally
// Declare = 1, that means one signal may be correspond multi-process die
While ($ pid = pcntl_wait ($ status, WNOHANG | WUNTRACED)> 0 ){
If (FALSE === pcntl_wifexited ($ status )){
Yii: log ("sub proccess {$ pid} exited unormally with code {$ status}", CLogger: LEVEL_WARNING, _ METHOD __);
} Else {
Yii: log ("sub proccess {$ pid} exited normally", CLogger: LEVEL_INFO, _ METHOD __);
}
$ This-> _ children --;
}
Break;
Case SIGINT:
Case SIGQUIT:
Case SIGHUP:
// Exit unexpectedly
$ This-> _ cleanup ();
Exit (0 );
Break;
Default:
Break;
}
}
[Notes for multi-process mode]
Variable sharing
Because it is a process, it can be understood as a copy of the main process. The execution starts from the call of pcntl_fork () and then runs after the main and sub-processes, avoiding layer-by-layer nesting of sub-processes, generally, after a sub-process is executed, exit (0) is used to exit. If a sub-process crashes during execution, it does not affect the main process or share variables with the main process.
Signal and select conflict
After pcntl_signal registers the signal, it will conflict with stream_select.
PHP Error [2]: stream_select (): unable to select [4]: Interrupted System call (max_fd = 10)
No solution was found and pcntl_signal was not used for monitoring.
Process recycling
After the sub-process exits through exit, it will become a zombie process and needs to be recycled through pcntl_wait.
In the centos test, the maximum number of processes is 32 thousand. by setting the total number of sub-processes, the maximum number of sub-processes is greater than the set value, and then calling pcntl_wait for recycling.
Socket read/write considerations
In the case of multiple processes, the same socket handle may be read simultaneously by multiple processes.
The solution is to read all the data in the master process and then send it to the sub-process for execution.
File operation notes
The filesize function may fail to be obtained or the size of the obtained file remains unchanged in the case of multiple processes.
Here, the system functions in linux are called directly.
$ File_size = @ filesize ($ logFile );
// Solve the problem that the file size cannot be obtained under concurrent conditions.
If (0 = $ file_size | $ this-> _ prevFileSize = $ file_size)
{
$ File_size = @ exec ('/usr/bin/stat-c % S'. escapeshellarg ($ logFile ));
Clearstatcache ();
}
After stress testing, 1000 of the concurrency can reach 350 requests per second. It should also be optimized.