php并行运行多任务,daemon守护进程
利用swoole框架,适合运行并行的长时间(一直运行)的任务.
如下
<?php
$redirect_stdout = false;
$workers = [];
$worker_num = 8;
cli_set_process_title('monitormain');//修改进程名,need php>5.5
//swoole_process::daemon(0, 1);/yuan
swoole_process::daemon(0, 0);//as a daemon
for($i = 0; $i < $worker_num; $i++)
{
$process = new swoole_process('child_async', $redirect_stdout);//创建子进程
$pid = $process->start();//子进程pid
$workers[$pid] = $process;
}
master_async($workers);
//异步主进程,用于与子进程通信等
function master_async($workers)
{
swoole_process::signal(SIGCHLD, function ($signo) use ($workers) {
$ret = swoole_process::wait();
$pid = $ret['pid'];
unset($workers[$pid]);
echo "Worker Exit, PID=" . $pid . PHP_EOL;
});
/**
* @var $process swoole_process
*/
/*与子进程通信
foreach($workers as $pid => $process)
{
swoole_event_add($process->pipe, function($pipe) use ($process) {
$recv = $process->read();
if ($recv) echo "From Worker: " . $recv;
});
$process->write("hello worker[$pid]\n");
}*/
}
function child_async(swoole_process $worker)
{
//echo "Worker: start. PID=".$worker->pid."\n";
//recv data from master
$GLOBALS['worker'] = $worker;
global $argv;
//$worker->name("{$argv[0]}: worker");//修改进程名
$worker->name("monitor");//修改进程名
swoole_process::signal(SIGTERM, function($signal_num) use ($worker) {
echo "signal call = $signal_num, #{$worker->pid}\n";
});
//do something
echo 'hello';
/*异步,同步时不需要
swoole_event_add($worker->pipe, function($pipe) use($worker) {
$recv = $worker->read();
echo "From Master: $recv\n";
$worker->write("hello master\n");
});*/
}
---------------------------------以下是完整代码----------------------
<?php
//php并行执行多个任务
//用于监控集群工作状态
//用法:终端执行:php monitor.php Monitor node 192.168.6.157 192.168.6.156....
$redirect_stdout = false;//重定向子进程的标准输入和输出
$workers = [];
isset($argv)?$worker_num = count($argv)-3:1;//$worker_num:子进程数
cli_set_process_title('monitormain');//修改进程名,need php>=5.5
swoole_process::daemon(1, 0);//as a daemon
//循环创建子进程
for($i = 0; $i < $worker_num; $i++)
{
$process = new swoole_process('child_async', $redirect_stdout);//创建子进程
$pid = $process->start();//子进程pid
$workers[$pid] = $process;
}
master_async($workers);//执行主进程
//异步主进程,用于与子进程通信等
function master_async($workers)
{
global $argv;
$argnum=2;
swoole_process::signal(SIGCHLD, function ($signo) use ($workers) {
$ret = swoole_process::wait();
$pid = $ret['pid'];
unset($workers[$pid]);
echo "Worker Exit, PID=" . $pid . PHP_EOL;
});
foreach($workers as $pid => $process)
{
$argnum++;
swoole_event_add($process->pipe, function($pipe) use ($process) {
//$recv = $process->read();//从子进程读消息
if ($recv) echo "From Worker: " . $recv;
});
$process->write("$argv[$argnum]");//向子进程写消息
}
}
//异步子进程
function child_async(swoole_process $worker)
{
$GLOBALS['worker'] = $worker;
global $argv;
$worker->name("monitor");//修改进程名
swoole_process::signal(SIGTERM, function($signal_num) use ($worker) {
echo "signal call = $signal_num, #{$worker->pid}\n";
});
//执行任务
swoole_event_add($worker->pipe, function($pipe) use($worker,$argv) {
$recv = $worker->read();//读取主进程消息
//echo "From Master: $recv ***\n";
//$worker->write("hello master\n");//向主进程写消息
$args= array('cli.php', $argv[1],$argv[2],$recv);
$worker->exec('/usr/bin/php',$args);//执行命令
});
}
评论 (0)