所属分类:php教程
php pcntl_fork进程不死掉的解决办法:1、打开相应的PHP代码文件;2、查看php多线程处理代码;3、通过“public function installSignal(){pcntl_signal(SIGTERM, [$this, 'sigHandle'])...};”方式安装信号处理器即可。
php入门到就业线上直播课:进入学习
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API调试工具:点击使用
本教程操作环境:windows7系统、PHP8.1版、Dell G3电脑。
php pcntl_fork 进程不死掉怎么办?
问题描述
第一次使用php多线程处理任务引起僵尸进程问题,原因是子进程没有发送结束信号,父进程没有等待子进程的结束
理解
pcntl_fork 返回-1:开启进程失败 0:表示当前是子进程 大于零:当前是父进程,返回值是子进程pid
fork的子进程代码执行完后必须exit(),发送结束信号。否则继续fork子进程。获取父进程pid = posix_getppid(), 当前pid = getmypid()或者posix_getpid()
父进程最好等待子进程执行结束回收子进程通过pcntl_wait()、pcntl_waitpid()实现同步、异步等待父进程循环子进程:
$result = pcntl_waitpid($pid_, $status, WNOHANG);
$result等于-1时代表子进程结束
登录后复制
信号处理器的作用是根据处理子进程返回的结束信号进行处理
public function run()
{
$this->installSignal();
// 获取当前pid getmypid()
$current_pid = posix_getpid();
// dump('当前pid:'.$current_pid);
cli_set_process_title('设置process_title');
$pids = [];
for($i = 0; $i < $this->forks; $i ++){
$pid = pcntl_fork();
if($pid == -1){
die('进程开启失败');
}else if($pid){
// 父进程得到子进程pid
dump('父进程');
dump('父进程得到子进程pid'.$pid);
$pids[] = $pid;
}else{
dump('子进程');
dump('父进程pid-'.posix_getppid());
// 子进程
dump("第{$i}个进程");
sleep(10);
dump("第{$i}个进程:等待10s");
// 发送结束信号
// exit(-1);
// posix_kill(getmypid(), SIGKILL);
posix_kill(getmypid(), SIGHUP);
}
}
// 父进程等待子进程执行结束
while($pids){
foreach($pids as $k => $pid_){
dump('父进程不阻塞-等待子进程结束');
$result = pcntl_waitpid($pid_, $status, WNOHANG);
dump($result);
if($result === -1){
dump('子进程返回状态'.$status);
unset($pids[$k]);
}
}
}
/**
* 信号处理器
*/
public function sigHandle($signo)
{
switch ($signo) {
case SIGTERM:
// 处理SIGTERM信号
dump('处理SIGTERM信号');
exit;
break;
case SIGHUP:
//处理SIGHUP信号
dump('处理SIGHUP信号');
exit(SIGHUP);
break;
case SIGUSR1:
dump('处理SIGUSR1信号');
break;
default:
// 处理所有其他信号
}
}
/**
* 安装信号处理器
*
*/
public function installSignal()
{
pcntl_signal(SIGTERM, [$this, 'sigHandle']);
pcntl_signal(SIGHUP, [$this,'sigHandle']);
pcntl_signal(SIGUSR1, [$this,'sigHandle']);
}
登录后复制
推荐学习:《PHP视频教程》
以上就是php pcntl_fork 进程不死掉怎么办的详细内容,更多请关注zzsucai.com其它相关文章!