写给 PHP 程序员的信号处理教程

bucai 2019-01-04

“ 今天晚上吃卤煮,领桌的妹子问我,这玩意儿能吃么?我:你觉得能吃就能吃。。。和内容无关的主题 

01

什么是信号

上图中,我为信号SIGINT注册了处理函数sigint_handle,捕获到信号后,输出内容后退出,简单易懂吧。执行  gcc -o run run.c && ./run ,然后 CTRL+C(会触发SIGINT信号) ,成功输出: 成功捕获到信号2! ,程序直接结束运行。

03

PHP的信号处理举例

写给 PHP 程序员的信号处理教程

pcntl_signal是PHP的信号处理注册方法,上面实现的功能和C实现的基本一致,不同的是,当前进程不会退出,并且多输出了一个signinfo(PHP是C写的,为啥刚刚C语言的没有信号相关的信息呢?因为PHP使用的是另一个信号函数 sigaction, 有兴趣的可以了解一下 )

04

PHP的信号处理并不是直接调用C

写给 PHP 程序员的信号处理教程

这个是pcntl初始化的时候,将pcntl_signal_dispatch注册为tick的处理函数

写给 PHP 程序员的信号处理教程

pcntl_signal会将处理函数放到信号集合中(PHP的hash table),而php_signale4最终会调用sigaction进行底层的信号管理。

写给 PHP 程序员的信号处理教程

这里我省略了大量代码,将关键的点标记了出来,其实PHP维护一个自己的信号集合,每当调用 pcntl_signal_dispatch时就会查询是否有信号,上面的SIG_BLOCK会将信号阻塞,这样只有我们把关键的代码执行完毕之后,再去触发信号处理函数以保证数据和程序逻辑的完整性。

05

PHP如何优雅的处理信号

经常见到身边的程序员们,每当需要重启PHP-FPM进程的时候,使用的招数是kill掉所有PHP进程,然后新启动。一般情况没啥问题,但有些时候可能某个进程的任务还没执行完,直接把人家中断了略显粗暴。其实只要你给PHP的Master进程发送一条USR2信号,它便会再处理完所有任务后,重启子进程,这才是所谓的优雅~

写给 PHP 程序员的信号处理教程

相关推荐