Ant*_*nio 9 php windows signals
我有一个独立的PHP脚本,我会处理从Windows操作系统发送的信号,以便在发出"终止信号"时进行正常关机.
我怎么能在Windows上这样做?
虽然这里唯一的另一个答案是简洁和准确,但它没有详细说明为什么Windows上没有信号支持.
首先,信号是一种与流程进行通信的相当有限且过时的方式.有更多更丰富的方法可以告知流程它需要放弃正在做的事情并做其他事情.即使在POSIX平台上,信号处理程序也非常轻量级 - 信号处理程序中的代码必须准备好/能够处理同时到达的多个信号.
PHP允许通过pcntl_signal()获得信号处理程序,但需要注意很多.在使用它们之前,代码必须调整在PHP传递到达处理程序的信号之前经过的"滴答"的数量.tick是在检查信号处理程序状态和运行必要的回调之前Zend(PHP的核心)将执行的指令数.它基本上是主执行循环中的繁忙循环.因此,如果遵循每滴答建议1,调整滴答将极大地减慢过程.对函数的评论表明,在大多数系统中,刻度值为100就足够了.理解处理程序如何工作的最简单方法是在幕后收集信号信息的实际信号处理程序,PHP偶尔会查询以查看处理程序是否被调用,发送了哪个信号等等 - 如果是,那么信息被传递到userland中的回调(即您的代码).这不是真正的信号处理,也不会是由于真正的信号处理带来的危险和困难.
第二个问题是,即使使用pcntl_signal()提供的伪信号处理程序支持,PHP也可能丢失有关发生的信号的信息.如果发生多信号情况,则不会通知脚本多次发生某些信号.刻度值越大,发生这种情况的可能性越大,尤其是在繁忙的系统上.
在大多数情况下,Windows并不真正使用信号.存在SetConsoleCtrlHandler()函数,用于捕获Ctrl + C和Ctrl + Break,大致相当于SIGINT.缺点是必须有一个连接到进程的控制台才能工作,并且不能由其他进程发送.该了TerminateProcess()函数等同于SIGKILL,这是不能被阻塞/下其他操作系统和SIGKILL信号处理在目标过程中不实际到达.除了这两个功能/信号之外,几乎没有共同之处.最终,Windows是一个非常不同的野兽.
查看信号的唯一原因是某种长期运行的PHP过程 - 每个人似乎都认为该语言不适合的任务(我完全不同意,但这是一个不同的讨论).当我了解到即使在POSIX操作系统下PHP中信号支持的局限性,我也认为它们并不能解决我的问题.正确的解决方案是完全忽略信号.对于SIGINT,应编写命令行脚本来处理提前终止的情况 - 也就是说,它们应该是幂等的.在PHP的世界中,信号在很大程度上是无关紧要的,因为还有其他更灵活,更丰富的解决方案,包括命名的互斥/事件,套接字,文件,命名管道,共享内存,服务管理器等.