当前位置: 首页 > 知识库问答 >
问题:

如何中断exec并终止子进程

曹智
2023-03-14

我试图用< code>exec()调用PHP CLI脚本中的一个长期运行的shell命令。但是我无论如何也想不出如何中断PHP脚本并杀死产生的子进程。好像我一调用< code>exec(),我的信号处理程序就被忽略了。下面的代码像我预期的那样工作;如果我向进程发送SIGTERM,它会回显< code>SIGTERM并立即退出。

<?php
  declare(ticks = 1);

  function sig_handler($signo) {
    switch ($signo) {
      case SIGTERM:
        echo 'SIGTERM' . PHP_EOL;
        flush();
        break;
      default:
    }
  }

  pcntl_signal(SIGTERM, 'sig_handler', false);

  sleep(60);
?>

但是,如果我替换< code > sleep(60);与< code > exec(' sleep 60 ');,直到睡眠结束,我才找到我的信号处理器。我有两个问题:

  1. 如何获取信号以使用 exec(或shell_execproc_open)?
  2. 捕获信号后,如何杀死 exec 生成的任何子进程?

共有1个答案

禹智渊
2023-03-14

文档确实说:

如果一个程序用这个函数启动,为了让它继续在后台运行,程序的输出必须被重定向到一个文件或另一个输出流。否则会导致PHP挂起,直到程序执行结束。

(我的重点)我想挂起也适用于信号处理器。

为了能够控制子进程,看起来您必须以老式的方式执行它们,使用fork exec:

switch ($pid = pcntl_fork()) {
  case -1: // failed to create process
     die('Fork failed');
  case 0: // child
     pcntl_exec($path,$args);
     die('Exec failed');
}

一旦父进程在$pid中有子进程的id,它就可以使用posix_kill($pid, SIGINT)向子进程发送SIGINT。

更新:显然您也可以使用proc_openproc_terminate

 类似资料:
  • 问题内容: 有没有办法终止Golang中以os.exec开始的进程?例如(来自http://golang.org/pkg/os/exec/#example_Cmd_Start), 是否可以提前3秒后终止该过程? 提前致谢 问题答案: 终止运行: 超时后终止运行: 该过程结束并且在3秒钟内收到了错误(如果有的话),并且该程序在完成之前被终止了。

  • 问题内容: 强制保持Node.js进程运行的最佳方法是什么,即使其事件循环不为空,从而防止进程终止?我能想到的最好的解决方案是: 如果您将间隔时间保持足够长,它将使间隔运行,而不会引起过多干扰。 有更好的方法吗? 问题的长版 我有一个使用Edge.js来注册回调函数的Node.js脚本,以便可以从.NET中的DLL内部对其进行调用。每秒将调用此功能1次,发送一个应打印到控制台的简单序列号。 Edg

  • 我有一个应用Gradle插件的项目。我的问题是,即使底层进程终止,它也不会终止:如果我运行这个: 带有仅包含系统的主系统。退出(0) 程序终止,但Gradle没有终止。当底层Java程序终止时,如何强制Gradle进程终止? 编辑:我知道我可以调用gradle——stop,但这需要另一个进程,这不是一个选项。

  • 在线程中,我有一个从用户控制台读取输入的循环。主线程正忙于Tkinter mainloop()。如何终止此程序? 主thead调用startGUI(),其中包含一个tk。mainloop()调用。当我按下窗口上的X关闭按钮(这是Linux)时,Tkinter关闭窗口,mainloop()返回。然后我试着关闭stdin,希望这个系统。stdin将关闭并导致系统故障。斯丁。readline()将以一个

  • 问题内容: 我正在使用以下命令启动子流程: 但是,当我尝试杀死使用: 要么 该命令一直在后台运行,所以我想知道如何才能真正终止该过程。 请注意,当我使用以下命令运行命令时: 发出时,它确实成功终止。 问题答案: 使用进程组,以便能够向组中的所有进程发送信号。为此,您应该将会话ID附加到生成的子进程的父进程中,在您的情况下这是一个外壳程序。这将使其成为流程的组长。因此,现在,当信号发送到流程组负责人

  • 问题内容: 子进程开始于 有没有办法确保在父异常终止时将其杀死?我需要在Windows和Linux上都能使用。 编辑: 如果存在使用其他启动进程的方法的解决方案,则可以放宽启动子进程的要求。 问题答案: 呵呵,我昨天自己在研究这个!假设您无法更改子程序: 在Linux上,可能是唯一可靠的选择。(如果绝对有必要终止子进程,那么您可能希望将终止信号设置为SIGKILL而不是SIGTERM;链接到的代码