【问题标题】:Cannot stop C daemon in certain situations from PHP在某些情况下无法从 PHP 停止 C 守护程序
【发布时间】:2017-10-08 22:12:51
【问题描述】:

我在 Linux 中创建了一个简单的 C 守护程序。守护进程设置为捕获 SIGTERM 信号,进行一些清理并终止。从命令行运行时,这将按预期运行。通过 kill 命令向守护程序发送 SIGTERM 会得到正确处理。

不过,我希望能够从 PHP 应用程序启动和停止守护程序。我在 PHP 中使用 exec() 来执行此操作。开始

exec("$daemon_name");

然后停止

exec("kill $daemon_pid");

以这种方式启动守护进程总是有效的,但停止则不行。事实上,当以这种方式启动时,从命令行执行 kill 也不起作用。现在只有“kill -9”有效,这显然不能进行所需的清理。据我所知,这个过程根本没有收到信号。

这才是真正吸引我的地方。当我在 SLES 12 或 OpenSuSE 42.2 上部署完全相同的配置时,它不起作用,但在 OpenSuSE 42.1 上,它确实起作用(我可以通过 PHP 启动和停止)。

这不是权限问题,我验证了这一点。

我不知道是什么导致进程无法接收到 SIGTERM 信号。查看“ps aux”和“ps -ef”的输出,我发现从命令行启动的守护进程和通过 PHP 启动的守护进程之间没有区别。

编辑: 感谢迄今为止所有的cmets。他们似乎都没有考虑到完全相同的代码可以在某些系统上运行,而在其他系统上则不行。我唯一能想到的是,守护进程是在不同的环境中启动的。问题:进程启动的环境中是否有任何东西会导致它忽略信号?

【问题讨论】:

  • 我已将问题跟踪到两种情况之间的块掩码差异。我为问题here 创建了一个新线程
  • 这个问题现在已经解决了。请参阅上面评论中的链接。

标签: php c linux daemon


【解决方案1】:

也许您的问题应该是为什么kill <pid> 可能不起作用。这不是 PHP 的特定问题。 kill 很容易被进程忽略。现在您提到它是一个 C 守护程序,但是,您没有提及该守护程序的作用。所以我只是假设你的守护进程等待 I/O,它没有正确配置超时,你杀死它。那么这个进程无论如何都不会被杀死。

您可以在此处阅读https://askubuntu.com/questions/59811/kill-pid-not-really-killing-the-process-why 了解可能的解决方案。

【讨论】:

  • 你也可以试试pkill process,它不需要<pid>,它使用进程的名称来代替
  • 你第一句的说法是正确的,但是为什么从命令行启动守护进程时kill起作用,而以其他方式启动则不起作用。我在提供的线程中也找不到任何线索。
  • @Marius 我只是在这里做假设,但是如果您要杀死的进程是父进程,那么您可以使用-P 参数。像这样pkill -P <pid>
  • 这将杀死所有具有父进程ID的进程
  • @Marius 有4个命令可以杀死一个进程,你都试过了吗?如果您的脚本正在创建多个进程,那么只杀死一个进程将无法解决问题。您必须找到一种方法来杀死所有父子进程。另见xkillkillall
猜你喜欢
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 2020-05-05
相关资源
最近更新 更多