In many cases, PHP is not suitable for resident SHELl processes. It does not have dedicated gc routines or effective memory management channels. so if you use PHP as the resident SHELL, you will often be exhausted by memory, resulting in abort and unhappy.
In addition, if the input data is invalid and the script does not detect it, resulting in abort, it will make you very unhappy.
So? What should we do?
Don't worry. multi-process will help you!
So, why?
Advantages:
1. When a multi-process is used, the kernel will be responsible for recycling resources after the sub-process ends.
2. If a multi-process is used, abnormal exit of the sub-process will not cause the Thread of the whole process to exit. The parent process also has the opportunity to rebuild the process.
3. A resident process is only responsible for task distribution, and the logic is clearer.
Then, how to do it?
Next, we use POSIX and Pcntl series functions provided by PHP to implement a PHP command parser. The main process is responsible for receiving user input and then fork sub-process execution, and is responsible for returning the end status of the sub-process.
The Code is as follows. I added a comment. If you do not understand the code, you can read the related functions of the manual or reply to the message.
#! /Bin/env php
/** A example denoted muti-process application in php
* @ Filename fork. php
* @ Touch date Wed 10 Jun 2009 10:25:51 PM CST
* @ Author Laruence
* @ License http://www.zend.com/license/3_0.txt PHP License 3.0
* @ Version 1.0.0
*/
/** Make sure this function can only run in SHELL */
If
(Substr (php_sapi_name (), 0, 3 )! = 'Cli ')
{
Die ("This Programe can only be run in CLI mode ");
}
/** Disable the maximum execution event limit. In CLI mode, this statement is not necessary */
Set_time_limit (0 );
$ Pid = posix_getpid (); // obtain the master process ID
$ User = posix_getlogin (); // obtain the user name
Echo
<
USAGE: [command | expression]
Input php code to execute by fork a new process
Input quit to exit
Shell Executor version 1.0.0 by laruence
EOD;
While
(True)
{
$ Prompt = "\ n {$ user} $ ";
$ Input = readline ($ prompt );
Readline_add_history ($ input );
If
($ Input = 'quit ')
{
Break;
}
Process_execute ($ input .';');
}
Exit (0 );
Function
Process_execute ($ input)
{
$ Pid = pcntl_fork (); // create a sub-process
If
($ Pid = 0)
{// Sub-process
$ Pid = posix_getpid ();
Echo
"* Process {$ pid} was created, and Executed: \ n ";
Eval ($ input); // resolution command
Exit;
}
Else
{// MAIN PROCESS
$ Pid = pcntl_wait ($ status, WUNTRACED); // get the sub-process end status
If
(Pcntl_wifexited ($ status ))
{
Echo
"\ N * Sub process: {$ return ['pid ']} exited with {$ status }";
}
}
}