Heute Abend habe ich geschmortes Schweinefleisch gegessen, und das Mädchen am Tisch fragte mich: Kann man das essen? Ich: Du kannst es essen, wenn du denkst, dass du es kannst. . . Ein Thema, das nichts mit dem Inhalt zu tun hat
Was ist ein Signal? Ein Signal ist ein Benachrichtigungsmechanismus (auch Software-Interrupt genannt) für den Prozess, wenn ein Ereignis auftritt. Wenn ein Prozess ein Signal empfängt, unterbricht der Kernel den vom Prozess ausgeführten Code und springt zur entsprechenden Signalverarbeitungsfunktion. Wenn die Verarbeitungsfunktion nicht unterbricht, wird die Ausführung nach der Ausführung der Verarbeitungsfunktion an der Stelle fortgesetzt, an der sie unterbrochen wurde. implementieren.
Wir schreiben Code im FPM-Modus und werden keine Probleme im Zusammenhang mit der Signalverarbeitung haben. Wie können jedoch einige speicherresidente Skripte im CLI-Modus frei neu gestartet, heruntergefahren und einige Aufräumarbeiten durchgeführt werden, bevor sie beendet werden (Verbindung trennen). , temporäre Dateien löschen usw.)?
C-Signalverarbeitungsbeispiel
Im Bild oben habe ich die Verarbeitungsfunktion sigint_handle
für das Signal SIGINT
nach der Signalerfassung und nach der Ausgabe registriert Der Inhalt ist einfach und leicht verständlich. Führen Sie gcc -o run run.c && ./run
aus, dann STRG+C
(das Signal SIGINT
wird ausgelöst) und erfolgreiche Ausgabe : Signal 2 wurde erfolgreich erfasst!
, und das Programm wird sofort beendet. Beispiel für die PHP-Signalverarbeitung 5605e8a17d80b .png"/>
SIGINT
注册了处理函数sigint_handle
,捕获到信号后,输出内容后退出,简单易懂吧。执行 gcc -o run run.c && ./run
,然后CTRL+C
(会触发SIGINT
信号),成功输出:成功捕获到信号2!
,程序直接结束运行。
PHP的信号处理举例
pcntl_signal
是PHP的信号处理注册方法,上面实现的功能和C实现的基本一致,不同的是,当前进程不会退出,并且多输出了一个signinfo
(PHP是C写的,为啥刚刚C语言的没有信号相关的信息呢?因为PHP使用的是另一个信号函数sigaction
,有兴趣的可以了解一下)
PHP的信号处理并不是直接调用C
这个是pcntl初始化的时候,将pcntl_signal_dispatch
注册为tick的处理函数
pcntl_signal
会将处理函数放到信号集合中(PHP的hash table),而php_signale4
最终会调用sigaction
进行底层的信号管理。
这里我省略了大量代码,将关键的点标记了出来,其实PHP维护一个自己的信号集合,每当调用pcntl_signal_dispatch
时就会查询是否有信号,上面的SIG_BLOCK
会将信号阻塞,这样只有我们把关键的代码执行完毕之后,再去触发信号处理函数以保证数据和程序逻辑的完整性。
PHP如何优雅的处理信号
经常见到身边的程序员们,每当需要重启PHP-FPM
进程的时候,使用的招数是kill掉所有PHP进程,然后新启动。一般情况没啥问题,但有些时候可能某个进程的任务还没执行完,直接把人家中断了略显粗暴。其实只要你给PHP的Master进程发送一条USR2
信号,它便会再处理完所有任务后,重启子进程,这才是所谓的优雅~
上图是我简单写的一个例子,如果我们想让进程优雅退出的时候,只需要发送SIGTERM
信号即可。需要注意的是SIGKILL
和SIGSTOP
信号会略过信号阻塞会将进程直接停止,还有就是信号会中断睡眠(SLEEP),sleep
pcntl_signal
ist die Signalverarbeitungsregistrierungsmethode von PHP. Die oben implementierten Funktionen sind grundsätzlich dieselben wie die in C implementierten. Der Unterschied besteht darin, dass der aktuelle Prozess nicht beendet wird und Geben Sie noch eine signinfo
aus (PHP ist in C geschrieben. Warum gibt es derzeit keine signalbezogenen Informationen in der C-Sprache? Weil PHP eine andere Signalfunktion sigaction
verwendet, diejenigen, die es sind Interessierte können mehr darüber erfahren)
PHPs Signalverarbeitung ruft C nicht direkt auf