오늘 밤에 돼지고기 조림을 먹고 있는데 테이블에 앉은 여자가 나에게 '이 음식은 먹을 수 있나요?'라고 물었습니다. 나: 먹을 수 있을 것 같으면 먹어도 돼요. . . 콘텐츠와 관련 없는 주제
신호란 무엇입니까
신호는 이벤트가 발생할 때 프로세스에 대한 알림 메커니즘(소프트웨어 인터럽트라고도 함)입니다. 프로세스가 신호를 받으면 커널은 프로세스에 의해 실행 중인 코드를 일시 중지하고 해당 신호 처리 기능으로 점프합니다. 처리 기능이 중단되지 않으면 처리 기능이 실행된 후 중단된 곳에서 실행이 계속됩니다. 구현하다.
FPM 모드에서 코드를 작성하면 신호 처리와 관련된 문제가 발생하지 않습니다. 그러나 CLI 모드의 일부 메모리 상주 스크립트의 경우 종료하기 전에 어떻게 자유롭게 다시 시작하고 닫고 정리 작업을 수행할 수 있습니까? 임시 파일 등을 삭제하시겠습니까?
C 신호 처리 예시
위 그림에서는 SIGINT
신호에 대한 처리 함수 sigint_handle
를 등록했습니다. 간단하고 이해하기 쉬운 콘텐츠 종료. gcc -o run run.c && ./run
을 실행한 다음 CTRL+C
(SIGINT
신호가 트리거됨)를 실행하면 성공적으로 출력됩니다. : 신호 2가 성공적으로 캡처되었습니다!
, 프로그램이 즉시 종료됩니다. 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