【问题标题】:PHP - kill exec on client disconnectPHP - 在客户端断开连接时杀死 exec
【发布时间】:2012-07-09 11:28:57
【问题描述】:


我的 C++ 应用程序有非常原始的 Web 前端。客户端(网络浏览器)进入 php 站点并用参数填写表单。比(在提交后)php 调用 exec 并且应用程序完成它的工作。 应用程序可以工作超过一分钟,并且需要大量的 RAM。

是否有可能检测到与客户端断开连接(例如在 Web 浏览器中关闭选项卡)。我想这样做,因为断开连接后客户端将无法看到计算结果,所以我可以杀死应用程序并释放服务器上的一些 RAM。

感谢您的任何帮助或建议。

【问题讨论】:

标签: php exec kill disconnect


【解决方案1】:

只要 C++ 程序在运行时产生输出,而不是在终止之前产生所有输出,请使用 passthru() 而不是 exec()

这会导致 PHP 在生成内容时将输出刷新到客户端,这允许 PHP 检测客户端何时断开连接。 PHP 将在客户端断开连接时终止并立即终止子进程(只要未设置ignore_user_abort())。

例子:

<?php

  function exec_unix_bg ($cmd) {
    // Executes $cmd in the background and returns the PID as an integer
    return (int) exec("$cmd > /dev/null 2>&1 & echo $!");
  }
  function pid_exists ($pid) {
    // Checks whether a process with ID $pid is running
    // There is probably a better way to do this
    return (bool) trim(exec("ps | grep \"^$pid \""));
  }

  $cmd = "/path/to/your/cpp arg_1 arg_2 arg_n";

  // Start the C++ program
  $pid = exec_unix_bg($cmd);

  // Ignore user aborts to allow us to dispatch a signal to the child
  ignore_user_abort(1);

  // Loop until the program completes
  while (pid_exists($pid)) {

    // Push some harmless data to the client
    echo " ";
    flush();

    // Check whether the client has disconnected
    if (connection_aborted()) {
      posix_kill($pid, SIGTERM); // Or SIGKILL, or whatever
      exit;
    }

    // Could be done better? Only here to prevent runaway CPU
    sleep(1);

  }

  // The process has finished. Do your thang here.

要收集程序的输出,请将输出重定向到文件而不是 /dev/null。我怀疑你需要安装pcntlposix,因为PHP 手册指出SIGxxx 常量是由pcntl 扩展定义的——尽管我从来没有安装过另一个所以我'我不确定。

【讨论】:

  • 我不能使用passthru(),因为我的应用程序生成的不是文本,而是图像。计算后 php 脚本传递给客户端链接到该图像(jpeg 文件)。
  • 好的,那么你确实有更多问题。这里有许多障碍需要克服,即您的 PHP 脚本需要不断向客户端推送数据以检测客户端是否已关闭连接,这意味着(除其他外)您需要将子进程与parent,以便您可以在外部程序运行时执行其他 PHP 代码。您的服务器是基于 Windows 或 *nix 的吗?你有 pcntl PHP 扩展可用吗?
  • 我有基于 Linux 的服务器,我可以重新编译 PHP 以获得 pcntl 支持。知道在计算期间我可以向客户端浏览器发送什么吗?
  • @user1126423 你现在给客户端发送什么?一个完整的 HTML 页面?目前我正在考虑空白,因为 HTML 与空白无关,尽管您可能需要在开始外部进程之前发送 &lt;head&gt; 并且最好是 &lt;body&gt; 的开头...
  • 是的,我正在发送整个 html 页面。我已经阅读了一些关于 pcntl 的内容。我读过在使用 PHP 作为 Apache 模块时我不能使用pcntl_fork()。真的吗?因为(我的项目经理要求)我不能使用 PHP 作为 CGI 应用程序。
猜你喜欢
  • 1970-01-01
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 2017-07-17
相关资源
最近更新 更多