今晚吃了红烧炖菜,领桌的妹子问我,这东西能吃吗?我:你觉得可以就可以吃。..一个与内容无关的话题什么是信号?信号是事件发生时进程的一种通知机制(也称为软件中断)。当一个进程接收到一个信号时,内核会暂停该进程正在执行的代码,跳转到相应的信号处理函数。如果处理函数没有被中断,处理函数执行完后,会继续执行中断的地方。实施。我们在FPM模式下写代码的时候,不会遇到信号处理相关的问题,但是CLI模式下一些常驻内存的脚本怎么能自由重启,关闭,退出前做一些清理工作(断开链接,删除临时文件,ETC。)?C中的信号处理示例在上图中,我为信号SIGINT注册了处理函数sigint_handle。捕获信号后,输出内容并退出。这很容易理解。执行gcc-orunrun.c&&./run,然后CTRL+C(会触发SIGINT信号),成功输出:successfullycapturedsignal2!,程序直接结束。PHP的信号处理实例pcntl_signal是一种PHP信号处理注册方法。上面实现的功能和C实现的基本一样,不同的是当前进程不会退出,多输出一个signinfo(PHP是C写的,为什么?刚才里面没有signal相关的信息C语言?因为PHP使用了另外一个信号函数sigaction,有兴趣的可以去了解)PHP的信号处理并没有直接调用C,这是pcntl初始化的时候。将pcntl_signal_dispatch注册为tick处理函数pcntl_signal会将处理函数放入信号集合(PHP哈希表),php_signale4最终会调用sigaction进行底层信号管理。这里我省略了很多代码,并标记了关键点。事实上,PHP维护着一组它自己的信号。每当调用pcntl_signal_dispatch时,它都会查询是否有信号。上面的SIG_BLOCK会阻塞信号,所以只有我们发送key代码执行后,触发信号处理函数,保证数据和程序逻辑的完整性。PHP如何优雅地处理信号?我经常看到我身边的程序员。每当需要重新启动PHP-FPM进程时,使用的技巧是杀死所有PHP进程,然后重新启动它们。一般情况下是没有问题的,但是有时候可能某个进程的任务没有完成,直接打断别人,有点不礼貌。其实只要给PHP的Master进程发送一个USR2信号,它就会在处理完所有任务后重启子进程。这就是所谓的优雅~上图是我简单写的例子。如果我们想让进程优雅地退出,发送SIGTERM信号即可。需要注意的是SIGKILL和SIGSTOP信号会跳过信号阻塞直接停止进程,信号会打断睡眠(SLEEP)。如果不执行睡眠,它将返回剩余的秒数。如果您有兴趣,可以尝试一下。信号相关的知识点其实还有很多,需要进一步研究~上面的PHP源码是7.1.25版本,每个版本可能不一样。关注公众号,一起学习成长~
