广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP怎么实现平滑关闭和重启
  • 897
分享到

PHP怎么实现平滑关闭和重启

2023-06-30 14:06:21 897人浏览 独家记忆
摘要

本篇内容介绍了“PHP怎么实现平滑关闭和重启”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!原理要实现平滑关闭/重启不难,这里先讲解两个知识点

本篇内容介绍了“PHP怎么实现平滑关闭和重启”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

原理

要实现平滑关闭/重启不难,这里先讲解两个知识点:

阻塞信号

当我们的程序正在处理一个任务的时候,你肯定不希望它中途被终止,比如说你在执行一个数据库事务,肯定不希望事务还没被提交进程就被终止了。

<?phpecho "开始执行事务" . PHP_EOL;// 模拟一些耗时的操作$finish_time = time() + 5;while (time() < $finish_time) {}echo "事务执行完毕" . PHP_EOL;

上面这段代码,如果你在第二个 echo 之前用 kill 命令去杀死这个进程,那么第二个 echo 就不会被执行了。那能不能做到在事务过程中暂时先忽略 kill 信号呢?

能。我们可以使用 pcntl_sigprocmask() 来阻塞信号,让事务完成之后再响应 kill 信号。

<?php// 阻塞信号$sig_set = array(SIGINT, SIGTERM); // 要阻塞的信号集合pcntl_sigprocmask(SIG_BLOCK, $sig_set); // SIG_BLOCK: 把信号加入到当前阻塞信号中echo date("[Y-m-d H:i:s]") . " 开始执行事务" . PHP_EOL;$finish_time = time() + 5;while (time() < $finish_time) {}echo date("[Y-m-d H:i:s]") . "事务执行完毕" . PHP_EOL;pcntl_sigprocmask(SIG_UNBLOCK, $sig_set); // SIG_UNBLOCK: 从当前阻塞信号中移出信号

同样的,在第二个 echo 之前按下 Ctrl + C 或者用 kill 命令去杀这个进程,你会发现第二个 echo 正常执行了,并且两条输出的时间间隔是 5 秒。

我们的常驻进程通常是在一个 while(true) 循环中去执行重复的任务,如果这么写的话:

<?phpwhile (true) {    pcntl_sigprocmask(SIG_BLOCK, $sig_set);    // ...    pcntl_sigprocmask(SIG_UNBLOCK, $sig_set);}

我们是可以保证一个事务不会被打断,但是我们的程序还不知道是不是已经接收到信号了,并且把阻塞信号移除之后进程立刻就退出了,没办法去做一些收尾工作(比如关闭文件)。

处理信号

为了解决上面提到的问题,我们需要在信号发生的时候去做收尾工作,然后再退出进程。

pcntl 扩展提供了一些信号相关的函数,我们可以使用 pcntl_signal() 和 pcntl_signal_dispatch() 来注册信号处理器和分发信号。

<?php$sig_handler = function ($signo) {    echo "收到信号 {$signo}" . PHP_EOL;};pcntl_signal(SIGINT, $sig_handler); // 给 SIGINT 信号注册一个处理器// 模拟耗时操作echo "开始执行事务" . PHP_EOL;$finish_time = time() + 5;while(true) {    if (time() > $finish_time) {        echo "事务执行完毕" . PHP_EOL;        break;    }}pcntl_signal_dispatch(); // 分发信号

执行上面这段代码并在 5 秒内按下 Ctrl + C,你会看到 sig_handler 被执行了;而如果不按下 Ctrl + C,那么 sig_handler 就不会被执行。

到这里你应该已经理解了 pcntl_signal() 和 pcntl_signal_dispatch() 的用法了,把它放到到刚刚的代码试试

<?php$sig_handler = function ($signo) {    echo "收到信号 {$signo}" . PHP_EOL;};$sig_set = array(SIGINT, SIGTERM);foreach ($sig_set as $sig) {    pcntl_signal($sig, $sig_handler); // 注册多个信号}// [1]while (true) {    // [2-1]    pcntl_sigprocmask(SIG_BLOCK, $sig_set);    // [2-2]    // ...    // [2-3]    pcntl_sigprocmask(SIG_UNBLOCK, $sig_set);    // [2-4]}// [3]

pcntl_signal_dispatch() 该放哪里呢?是 [1] [2] 还是 [3]?先动手试一下

然后你会发现,只有放在 [2] 才能让信号处理器执行。同时这个实验也告诉我们 pcntl_signal_dispatch() 要在信号发生后才会使处理器执行:放在 [1] 时,除非你手速足够快,不然在你按下 Ctrl + C 或者是 kill 之前就已经执行过了;而放在 [3] 它就永远没机会执行。

至于放在 [2] 的哪个位置,我建议是放在 [2-4],因为这个时候已经处理完任务了。

拼起来

到这里你已经了解平滑关闭/重启的原理了,我们把上面的半成品代码(因为在收到信号后可能还会进入下一层循环)整理一下:

<?php$running = true;$sig_handler = function ($signo) use (&$running) {    echo "收到信号 {$signo}" . PHP_EOL;    // 做收尾工作    $running = false;};$sig_set = array(SIGINT, SIGTERM, SIGUSR2 );foreach ($sig_set as $sig) {    pcntl_signal($sig, $sig_handler); // 注册多个信号}while ($running) {    pcntl_sigprocmask(SIG_BLOCK, $sig_set);    // ... 业务逻辑    pcntl_sigprocmask(SIG_UNBLOCK, $sig_set);    pcntl_signal_dispatch();}

我们就得到了一个可以平滑程序的常驻进程框架,你也可以把它封装成一个类。

“PHP怎么实现平滑关闭和重启”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: PHP怎么实现平滑关闭和重启

本文链接: https://www.lsjlt.com/news/329668.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PHP怎么实现平滑关闭和重启
    本篇内容介绍了“PHP怎么实现平滑关闭和重启”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!原理要实现平滑关闭/重启不难,这里先讲解两个知识点...
    99+
    2023-06-30
  • PHP平滑关闭/重启的实现方法
    目录前言原理阻塞信号处理信号拼起来思考前言 写过 CLI 常驻进程的老司机肯定遇到过这么一个问题:在需要更新程序的时候,我要怎样才能安全关闭老进程?你可能会想到 NGINX...
    99+
    2022-11-13
  • nginx怎么关闭、重启、和启动
    本篇内容主要讲解“nginx怎么关闭、重启、和启动”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“nginx怎么关闭、重启、和启动”吧!关闭service nginx stop...
    99+
    2023-06-28
  • Go项目实现优雅关机与平滑重启功能
    目录前言什么是优雅关机?实现原理实现优雅重启实现平滑重启测试总结前言 优雅关机就是服务端关机命令发出后不是立即关机,而是等待当前还在处理的请求全部处理完毕后再退出程序,是一种对客户端...
    99+
    2022-11-11
  • Golang怎么创建守护进程和平滑重启
    本篇内容介绍了“Golang怎么创建守护进程和平滑重启”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1)生成守护进程直接上代码:packag...
    99+
    2023-06-20
  • linux下php-fpm怎么开启和关闭
    这篇文章主要介绍了linux下php-fpm怎么开启和关闭的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇linux下php-fpm怎么开启和关闭文章都会有所收获,下面我们一起来看看吧。所以启动、关闭和重新加载的...
    99+
    2023-07-05
  • MySQL的启动与关闭怎么实现
    本篇内容介绍了“MySQL的启动与关闭怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2023-04-14
    mysql
  • Innodb关键特性之怎么实现启动、关闭和恢复
    这篇文章主要讲解了“Innodb关键特性之怎么实现启动、关闭和恢复”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Innodb关键特性之怎么实现启动、关闭和恢...
    99+
    2022-10-18
  • Android怎么实现微信侧滑关闭页面效果
    这篇文章主要介绍了Android怎么实现微信侧滑关闭页面效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。原理在每个Activity里面都有一个底层的View,也就是所谓的r...
    99+
    2023-05-30
  • C#实现远程关闭和重启计算机的示例代码
    目录实践过程效果代码实践过程 效果 代码 public partial class frmEdit : Form { public frmEdit() { ...
    99+
    2022-12-29
    C#远程关闭 重启计算机 C#关闭计算机 C#重启计算机
  • vbs怎么实现的定时关机或重启
    这篇文章主要讲解了“vbs怎么实现的定时关机或重启”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vbs怎么实现的定时关机或重启”吧!代码如下:'定时关机或重启的脚本,在windows...
    99+
    2023-06-08
  • php怎么实现关闭浏览器继续执行
    在PHP中,一旦执行完成,就会将输出发送给浏览器,并且关闭与浏览器的连接。所以,不能直接实现关闭浏览器后继续执行PHP代码。 然而,...
    99+
    2023-10-27
    php
  • 关闭EBS后重新开启出现concurrent manager异常及cmclean.sql慢问题该怎么办
    今天就跟大家聊聊有关关闭EBS后重新开启出现concurrent manager异常及cmclean.sql慢问题该怎么办,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一般在EBS ...
    99+
    2023-06-06
  • win10怎么实现快捷键快速开启与关闭蓝牙功能
    本篇内容主要讲解“win10怎么实现快捷键快速开启与关闭蓝牙功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“win10怎么实现快捷键快速开启与关闭蓝牙功能”吧!具体操作:打开设置以后,选择【设...
    99+
    2023-06-27
  • 怎么用bat和reg实现关闭局域网共享
    这篇文章主要为大家展示了“怎么用bat和reg实现关闭局域网共享”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“怎么用bat和reg实现关闭局域网共享”这篇文章吧。关闭局域网共享.cmd代码如下:...
    99+
    2023-06-09
  • SpringBoot项目怎么实现关闭数据库配置和springSecurity
    这篇文章主要介绍“SpringBoot项目怎么实现关闭数据库配置和springSecurity”,在日常操作中,相信很多人在SpringBoot项目怎么实现关闭数据库配置和springSecurity问题上存在疑惑,小编查阅了各式资料,整理...
    99+
    2023-06-20
  • shell脚本怎么实现监控php-fpm并自动重启服务
    这篇文章主要讲解了“shell脚本怎么实现监控php-fpm并自动重启服务”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“shell脚本怎么实现监控php-fpm并自动重启服务”吧!脚本代码:...
    99+
    2023-06-09
  • Oracle数据库产重启服务和监听程序怎么实现
    这篇文章主要介绍“Oracle数据库产重启服务和监听程序怎么实现”,在日常操作中,相信很多人在Oracle数据库产重启服务和监听程序怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Oracle数据库产重...
    99+
    2023-06-22
  • vue路由跳转打开新窗口和关闭窗口怎么实现
    本篇内容主要讲解“vue路由跳转打开新窗口和关闭窗口怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue路由跳转打开新窗口和关闭窗口怎么实现”吧!vue路由跳转打开新窗口和关闭窗口需求:...
    99+
    2023-07-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作