- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在开发一个定期调用后台进程的应用程序。其中一个被 cron 调用,但我正在寻找更强大的东西,所以我将它转换为在 Supervisor 下运行。 (它可能会运行 10 分钟,在此期间它可以检测要执行的工作或空闲状态。一旦退出,Supervisor 将自动重新生成一个干净的实例。)
由于 Supervisor 更擅长确保只有指定数量的实例并行运行,我可以让它们运行更长时间。然而,这确实意味着我的进程更有可能接收到终止信号,要么是直接来自 kill
,要么是因为它们已通过 Supervisor 停止。因此,我正在试验如何在 PHP 中处理此问题。
看起来基本的解决方案是使用 pcntl_signal()
像这样:
declare(ticks = 1);
pcntl_signal(SIGTERM, 'signalHandler');
pcntl_signal(SIGINT, 'signalHandler');
function signalHandler($signal) {
switch($signal) {
case SIGTERM:
case SIGINT:
echo "Exiting now...\n";
exit();
}
}
但是,我的代码中有几点可以通过谨慎的关机处理来完成。一种方法是让一个处理程序调用这些不同的东西,但它需要一些重构,我想避免这种重构。另一种方法是在我需要的任何地方添加 pcntl_signal()
,但不幸的是,一次似乎只能安装一个处理程序。
但是,看起来我可能能够使用register_shutdown_function()
.这不会自行捕获 ^C
或其他终止信号,手册在这一点上非常清楚:
Shutdown functions will not be executed if the process is killed with a SIGTERM or SIGKILL signal
令人惊讶的是,我发现如果我使用 pcntl_signal()
来执行退出,那么确实会调用关闭处理程序。此外,由于一个人可以有多个关闭处理程序,这很好地解决了我的问题 - 我的代码中希望优雅地处理终止的每个类都可以捕获和管理自己的关闭。
我最初的问题是,为什么这样做有效?我试过在没有信号处理程序的情况下注册一个关闭函数,这似乎没有被调用,正如手册所说。我猜 PHP 会保持该进程存活以处理信号,这会导致调用关闭处理程序?
此外,当手册对它产生怀疑时,我可以依赖这种行为吗?我正在使用 PHP 5.5,目前还不想升级到 PHP7。所以我很想知道这是否适用于 5.5 和 5.6,以及各种发行版。
当然,它是否会(或不会)在 7.0 和/或 7.1 上工作也很有趣 - 我知道 ticks will be handled differently在 7.1 中,因此更有可能出现不同的行为。
最佳答案
PHP 用户关闭函数在普通进程终止期间被调用,有点类似于在其他编程语言中使用 atexit
注册的函数。显式 exit
或脚本末尾的隐式退出是普通进程终止。
然而,信号死亡是非正常的进程终止。 SIGTERM 的默认行为(以及 SIGKILL 的强制行为)是立即终止正在运行的进程,而不运行任何清理处理程序。
当您使用 pcntl_signal
拦截 SIGTERM 时,您正在安装不同的行为并让您自己有机会体验普通的进程终止。
是的,您可以依赖这种行为。虽然主要的手册条目并不明确,但您引用的“注释”的其余部分如下:
[Y]ou can use
pcntl_signal()
to install a handler for a SIGTERM which usesexit()
to end cleanly.
关于php - 如果设置了 pcntl_signal(),我可以依赖在 SIGTERM 上调用的 register_shutdown_function() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38419471/
当前在我的 Windows 机器上使用 Codeception 运行 PHPUnit 时出现错误: [PHPUnit_Framework_Exception] Use of undefined con
当我的 Dockerfile 以 结尾时 CMD node . docker 使用命令 /bin/sh -c "node ." 运行该容器而不是简单的 node . (我知道,我可以用 CMD ["n
在Airflow v2.6.3上,我每天运行Spark作业。每隔一段时间,DAG中的成功作业都会通过EMR传感器重试该作业。重试的作业将显示“此实例的状态已在外部设置为up_for_retry。正在终
$ cat SIGTERM #!/bin/bash set -eu flag_file=$(xdg-user-dir DESKTOP)/SIGTERM-TRAPPED trap 'touch "$fl
我有一个单线程进程,它不会因 kill -TERM 而死亡。过程 信号掩码不显示 SIGTERM 被阻止。我正在执行“杀死” 根。我可以使用 SIGKILL 终止进程,但这是更大范围的一部分 系统,我
我有一个 bash 脚本调用 run.sh启动多个进程 #!/bin/bash proc1 & proc2 & proc3 & final # this runs until sigterm 当我执行
我正在摆弄多处理和信号。我正在创建一个池,并让工作人员捕获 SIGTERM。没有明显的原因,我观察到子进程随机接收 SIGTERM 。这是一个 MWE: import multiprocessing
Java 有没有办法处理接收到的 SIGTERM? 我正在运行一个 java 服务,但不想在用户注销时关闭我的 java 服务。 只想覆盖 sigterm 关闭处理程序,但保留其余信号的处理程序。 d
操作系统 (Linux) 可以向进程发送 SIGTERM 吗?如果是,什么时候?在什么情况下?例如,当我的进程写入不正确的地址内存时,操作系统会向它发送 SIGSEGV。提前致谢 最佳答案 Can O
我正在 try catch SIGTERM 信号并在来自 Linux 守护进程的处理程序中打印一条消息: void SigStop_Handler(int sig) { D(printf("**
我有一个简单的守护进程可以归结为 #include #include #include #include #include #include bool running = true; st
Java中有没有办法处理收到的SIGTERM? 我正在运行 java 服务,但不想在用户注销时关闭我的 java 服务。 只想覆盖 sigterm 关闭处理程序,但保留其余信号的处理程序。 detai
我有一个通过响应信号来运行的 C 程序。一些信号导致父进程 fork 。这允许在父级继续响应信号的同时进行其他处理。 当父级收到 SIGTERM 时,我希望 fork 的子级也收到 SIGTERM。在
我正在做这样的事情 def exitHandler(self, *args): self.stopThreads() sys.exit(2) 然后我在我的 self.run 中注册了该
我用c设计了一个消息传递接口(interface),用于在我的系统中运行的不同进程之间提供通信。该接口(interface)为此目的创建 10-12 个线程,并使用 TCP 套接字提供通信。 它工作正
我有一个可以启动和关闭进程的类。但似乎并没有关闭该进程。 我的python代码,还有其他方法,但它们工作得很好。: class KismetInstance: """Creates a kis
我的守护进程(仅限 Linux)具有以下信号处理程序: static void signal_handler(int id, siginfo_t *si, void *context) { i
有一个守护进程有两个线程:th1,th2。 th2 使用 read(2) 读取套接字。 如果我用 SIGTERM 终止守护进程,th1 会捕获并处理信号(设置终止标志),在调用守护进程析构函数之后,它
我的程序如下: #include #include #include #include int main() { struct sigaction new_sa; struct
如果 Python 接收到 SIGTERM 但没有为其注册信号处理程序,默认情况下会在幕后做什么? 最佳答案 基于 Thomas Wouters 的回答,python 没有为 SIGTERM 信号注册
我是一名优秀的程序员,十分优秀!