php进程与信号
2021-01-21 06:14
标签:child ast ase ctrl UNC handle oba bcd ace php进程与信号 标签:child ast ase ctrl UNC handle oba bcd ace 原文地址:https://blog.51cto.com/phpme/2510525
class SignalDemo
{
public $time_start;
public $pid_childs = [];
public $pid_childs_kill = [];
public $config;
public $master_pid;
public $master_status = 1;
public $str = ‘无‘;
public function __construct($config)
{
$this->config = $config;
$this->time_start = date(‘Y-m-d H:i:s‘);
}
public function run()
{
declare(ticks=1); //pcntl_signal_dispatch();
$this->master_pid = posix_getpid();//主id
$this->clear();//清屏
$this->command();//指令
$this->installSignal();//安装信号
//获取多进程任务
$task_info = $this->config[‘task_info‘];
foreach ($task_info as $info) {
$this->forkOneTask($info);//开启子进程
}
while ($this->master_status) {
$this->printStr();//输出信息
//守护子进程,以下是模拟子进程结束
foreach ($this->pid_childs as $k => $pid) {
posix_kill($pid, SIGUSR1);
pcntl_waitpid($pid, $status);
unset($this->pid_childs[$k]);
$this->str = ‘主进程把子进程:‘ . $pid . ‘杀掉了‘;
$this->printStr();
sleep(20);
}
$this->str = ‘无‘;
sleep(1);
}
echo ‘您按了 ctrl+c,主进程结束~~~‘;
}
//开启一个进程
public function forkOneTask($info)
{
$pid = pcntl_fork();
if ($pid === -1) {
echo ‘error‘;
exit;
}
if ($pid) {
$this->pid_childs[] = $pid;
} else {
//子进程
while (true) {
//做你想做的事。。。。。
sleep(2);
if (is_array($this->pid_childs_kill) && in_array(posix_getpid(), $this->pid_childs_kill)) {
exit();
}
}
}
}
//安装信号
public function installSignal($handler = ‘signalHandler‘)
{
pcntl_signal(SIGINT, array($this, $handler));
pcntl_signal(SIGHUP, array($this, $handler));
pcntl_signal(SIGUSR1, array($this, $handler));
}
//收到信号回调
public function signalHandler($signal)
{
switch ($signal) {
case SIGINT:
if (posix_getpid() == $this->master_pid) {
$this->master_status = 0; //设置主进程完毕
} else {
//子进程逻辑
$this->pid_childs_kill[] = posix_getpid();
}
break;
case SIGUSR1:
$this->pid_childs_kill[] = posix_getpid();
break;
}
}
//运行指令
public function command()
{
// 检查运行命令的参数
global $argv;
$start_file = $argv[0];
// 命令
$command = isset($argv[1]) ? trim($argv[1]) : ‘start‘;
// 进程号
$pid = isset($argv[2]) ? $argv[2] : ‘‘;
// 根据命令做相应处理
switch ($command) {
case ‘start‘:
break;
case ‘stop‘:
exec("ps aux | grep $start_file | grep -v grep | awk ‘{print $2}‘", $info);
if (count($info) $v) {
$loadavg[$k] = round($v, 2);
}
return implode(", ", $loadavg);
}
//打印到屏幕
public function printStr()
{
$display_str = ‘‘;
$display_str .= "-----------------------