Process

    • pcntl没有提供进程间通信的功能
    • pcntl不支持重定向标准输入和输出
    • pcntl只提供了fork这样原始的接口,容易使用错误
    • 支持重定向标准输入和输出,在子进程内echo不会打印屏幕,而是写入管道,读键盘输入可以重定向为管道读取数据
    • 配合Event模块,创建的PHP子进程可以异步的事件驱动模式
    • 提供了exec接口,创建的进程可以执行其他程序,与原PHP父进程之间可以方便的通信
    • 子进程异常退出时,自动重启
    • 主进程异常退出时,子进程会继续执行,完成所有任务后退出
    1. (new class{
    2. public $mpid=0;
    3. public $works=[];
    4. public $max_precess=1;
    5. public $new_index=0;
    6. public function __construct(){
    7. try {
    8. swoole_set_process_name(sprintf('php-ps:%s', 'master'));
    9. $this->mpid = posix_getpid();
    10. $this->run();
    11. $this->processWait();
    12. }catch (\Exception $e){
    13. }
    14. }
    15. public function run(){
    16. for ($i=0; $i < $this->max_precess; $i++) {
    17. $this->CreateProcess();
    18. }
    19. }
    20. public function CreateProcess($index=null){
    21. $process = new swoole_process(function(swoole_process $worker)use($index){
    22. if(is_null($index)){
    23. $index=$this->new_index;
    24. $this->new_index++;
    25. }
    26. swoole_set_process_name(sprintf('php-ps:%s',$index));
    27. for ($j = 0; $j < 16000; $j++) {
    28. $this->checkMpid($worker);
    29. echo "msg: {$j}\n";
    30. sleep(1);
    31. }
    32. }, false, false);
    33. $pid=$process->start();
    34. $this->works[$index]=$pid;
    35. return $pid;
    36. }
    37. public function checkMpid(&$worker){
    38. if(!swoole_process::kill($this->mpid,0)){
    39. $worker->exit();
    40. }
    41. }
    42. public function rebootProcess($ret){
    43. $pid=$ret['pid'];
    44. $index=array_search($pid, $this->works);
    45. if($index!==false){
    46. $index=intval($index);
    47. $new_pid=$this->CreateProcess($index);
    48. echo "rebootProcess: {$index}={$new_pid} Done\n";
    49. return;
    50. }
    51. throw new \Exception('rebootProcess Error: no pid');
    52. }
    53. public function processWait(){
    54. while(1) {
    55. if(count($this->works)){
    56. $ret = swoole_process::wait();
    57. if ($ret) {
    58. $this->rebootProcess($ret);
    59. }
    60. }else{
    61. break;
    62. }
    63. }
    64. }