$pid) { if($k==0){//reload跳过master进程 if($type=='reload'||$type=='restart'){ $masterPid = $pid; continue; } } exec("kill -9 $pid"); file_put_contents($worklogFile,date('Y-m-d H:i:s')."##{$type}--kill {$pid} \n", FILE_APPEND | LOCK_EX); unset($pidlist[$k]); } unlink($pidFile);//删除进程记录文件 } //创建多子进程 function createWorkProcess($process_num) { global $children_list,$chiledNum; for($i=0;$i<$process_num;$i++){ $pid = pcntl_fork(); if($pid == -1){ exit("err:fork children fail"); } $chiledNum++; if($pid == 0){//业务功能逻辑部分 $tpid = posix_getpid();//当前子进程pid cli_set_process_title("mp_work_{$chiledNum}");//设置当前进程名 doWork2($chiledNum); exit(0); } array_push($children_list, $pid); } return $process_num==1?$pid:$children_list; } //======工作业务逻辑======== function doWork($chiledNum){ include(dirname(__FILE__)."/../crontab/crontab.inc.php"); include(dirname(__FILE__)."/../com.php"); $memoryLogFile = dirname(__FILE__)."/../deBUG/work/memoryLog_{$chiledNum}.log"; $thisWPid = posix_getpid(); while (true) { sleep(2); $res = oo::async()->do_async($chiledNum); if(!$res){ oo::commonOprDb('common')->close(); } } } function doWork2($chiledNum){ include(dirname(__FILE__)."/../crontab/crontab.inc.php"); include(dirname(__FILE__)."/../com.php"); $memoryLogFile = dirname(__FILE__)."/../deBUG/work/memoryLog_{$chiledNum}.log"; $thisWPid = posix_getpid(); while (true) { sleep(5); file_put_contents($memoryLogFile,date('Y-m-d H:i:s')."##PID:{$thisWPid} -chiled:{$chiledNum} -do:ok \n"); try{ // $memoryOne = memory_get_usage()/1024; $res = oo::async()->do_async($chiledNum); // $memoryTwe = memory_get_usage()/1024; // file_put_contents($memoryLogFile, date('Y-m-d H:i:s')."##PID:{$thisWPid} - startMemory:{$memoryOne} - endMemory:{$memoryTwe}\n",FILE_APPEND | LOCK_EX); if(!$res){ $err = error_get_last(); throw new Exception('任务异常-'.json_encode($err)); } }catch (Exception $e){ $msg = $e->getMessage(); file_put_contents($memoryLogFile,date('Y-m-d H:i:s')."##PID:{$thisWPid} - error:{$msg} \n"); } //大于100M内存退出程序,防止内存泄漏被系统杀死导致任务终端 if(memory_get_usage()>100*1024*1024){ exit('内存溢出'); } } } //========================== if(!isset($argv[1])||!in_array($argv[1],$actList)){ useageExit(); } //结束进程 if($argv[1] == 'stop'){ killPids('stop'); file_put_contents($worklogFile, date('Y-m-d H:i:s')."##work is stop <<===\n=======\n", FILE_APPEND | LOCK_EX); exit(0); } //验证扩展 if (!extension_loaded("pcntl")) { die("require pcntl extension loaded"); } //验证运行模式 if (substr(php_sapi_name(), 0, 3) !== 'cli') { die("This Programe can only be run in CLI mode"); } //重载子进程(尚未完整) if($argv[1] == 'reload'){ exit(0); killPids('reload'); createWorkProcess($process_num);//创建子进程 array_unshift($children_list,$masterPid); file_put_contents($pidFile,implode(" ", $children_list)); file_put_contents($worklogFile, date('Y-m-d H:i:s')."##work is reload \n",FILE_APPEND | LOCK_EX); } //启动进程 if($argv[1]!= 'start') { usageExit(); } if(is_file($pidFile)) { die("mp_work is run. \n"); } $pid = pcntl_fork();//分出子进程下行 // 创建子进程失败 if ( $pid == -1 ) { die("err: start server fail. can not create process.\n"); } elseif ( $pid > 0 ) { exit(0); } //创建新会话,防止工作进程关联控制终端 if(-1 ==posix_setsid()){ die("err: create session id fail"); } $masterPid = posix_getpid();//当前进程pid cli_set_process_title('mp_work_master');//设置当前进程名 createWorkProcess($process_num);//创建子进程 $childstr = json_encode($children_list); echo "work is start===master:{$masterPid}===children_list:{$childstr}"."\r\n"; array_unshift($children_list,$masterPid);//master进程入进程组 file_put_contents($pidFile,implode(" ", $children_list)); file_put_contents($worklogFile, date("Y-m-d H:i:s")."##work is start ===>>\n", FILE_APPEND | LOCK_EX); //监控 while (true) { $pid = pcntl_wait($status/*, WNOHANG*/); if ( $pid > 0 && in_array($pid,$children_list) ) { sleep(2); unset($children_list[array_search($pid, $children_list)]);//移除进程组中的被kill pid $newpid = 0; // $newpid = createWorkProcess(1);//创建新子进程 unlink($pidFile); file_put_contents($pidFile,implode(" ", $children_list)); file_put_contents($worklogFile, date('Y-m-d H:i:s')."##work is restart (out {$pid} join {$newpid})\n",FILE_APPEND | LOCK_EX); } }