Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将PHP进程作为守护进程运行,同时从后台安全地终止它_Php_Kill Process_Daemons - Fatal编程技术网

将PHP进程作为守护进程运行,同时从后台安全地终止它

将PHP进程作为守护进程运行,同时从后台安全地终止它,php,kill-process,daemons,Php,Kill Process,Daemons,我们正在运行一个PHP守护进程,该守护进程查看队列,接收工人作业并生成工人来处理它。工人自己在继续工作之前在特定位置获得锁 我们以nohup后台进程的形式生成守护进程 整个体系结构似乎都能工作,除非出于任何原因我们必须终止进程。如果我们使用-9杀死它们,就无法在工作进程中捕获它并在死之前释放锁 如果我们使用小于-9的任何东西(比如TERM或HUP),那么守护进程或工作进程似乎都不会收到它 有人用更好的方法解决了这个问题吗 (PS:BTW,由于其他考虑,我们可能无法改变我们的实现语言,所以请只考虑

我们正在运行一个PHP守护进程,该守护进程查看队列,接收工人作业并生成工人来处理它。工人自己在继续工作之前在特定位置获得锁

我们以nohup后台进程的形式生成守护进程

整个体系结构似乎都能工作,除非出于任何原因我们必须终止进程。如果我们使用-9杀死它们,就无法在工作进程中捕获它并在死之前释放锁

如果我们使用小于-9的任何东西(比如TERM或HUP),那么守护进程或工作进程似乎都不会收到它

有人用更好的方法解决了这个问题吗


(PS:BTW,由于其他考虑,我们可能无法改变我们的实现语言,所以请只考虑基于PHP的解决方案)

你需要捕获信号(SIGTION)。这可以通过功能实现。这将为您提供在调用exit之前执行任何必要功能的选项。

我也曾经遇到过相关问题。让我解释一下。我有一个php“守护进程”,它的工作方式就像下载程序。它定期访问提要并从网上下载(laaaarge)内容。守护进程必须在某个时间停止,比如说早上5点,以防止它在白天使用整个bandwith。我决定使用cronjob将SIGTERM发送到0500的守护进程

在守护进程中,我有以下代码:

pcntl_signal(SIGTERM, array($this, 'signal_handler'));
其中,
信号处理器
如下所示:

public function signal_handler($signal) {
    // some cleanup code 
    exit(1);
}
不幸的是,这不起作用:|

我花了很长时间才弄清楚到底发生了什么。我发现的第一件事是,我必须在init上调用该方法才能启用信号调度。引用文档():

如果您以CLI和“守护进程”(即在循环中)的形式运行PHP,则必须在每个循环中调用此函数,以检查是否有新信号正在等待调度

好的,到目前为止,它似乎有效。但我很快意识到,在某些条件下,即使这样也不会像预期的那样起作用。有时,守护进程只能像以前一样通过
kill-9
-停止

有什么问题吗?。。答:我的程序调用了
wget
,通过
shell\u exec
下载文件。问题是,
shell\u exec()
阻塞等待子进程终止。在阻塞等待期间,没有进行任何信号处理,只能使用SIGKILL终止该进程-这很难。还有一个问题是,在杀死父进程后,子进程变成了僵尸进程,因此必须逐个终止

我的解决方案是使用
proc\u open()
执行子进程,并对其输出使用
stream\u select()
,以实现非阻塞IO

现在它就像一个符咒如果你需要进一步的信息,请不要犹豫发表评论


注意:如果您使用的是PHP<5.3,则必须使用`

declare(ticks=1);

而不是
pcntl\u信号发送()
。为此,您可以查阅的文档。但是如果可能的话,您应该升级到PHP>=5.3

只需添加勾号即可解决问题:

// tick use required as of PHP 4.3.0
declare(ticks = 1);
不考虑这一点会导致我的代码无法工作


*(不幸的是,pcntl_信号的文档没有以吸引更多注意力的方式提及它。)*

它是PHP5.3(或更高版本)吗?如果是,您是否使用了
pcntl_signal_dispatch()位于守护程序代码之上,还是以其他方式声明的
标记
?主守护进程是否在等待child?孩子们有没有阻止IO?SIGKILL有点残忍;当你在前台运行SIGTERM时,它能工作吗?声明ticks似乎起到了作用。不幸的是,pcntl_信号的文档并没有以更引人注目的方式提及它。声明后,它已开始按预期工作。@hek2mgl请随意填写答案,我将接受它,或者我将等到明天自己填写答案。@Shreeni Ok,将回答!:)正如问题中提到的,尽管通过pcntl_信号设置了处理程序,但似乎没有捕获SIGTERM。我的问题通过声明ticks:declare(ticks=1)得到了解决@Shreeni这是因为pcntl_signal_dispatch()与PHP5.3一样工作,
declare(ticks=1)
是PHP5.3的建议解决方案。您正在使用PHP5.2吗?我真的不相信