我的 C++ 应用程序有非常原始的 Web 前端。客户端(网络浏览器)进入 php 站点并用参数填写表单。比(在提交后)php 调用exec并且应用程序完成它的工作。应用程序可以工作超过一分钟,并且需要大量的 RAM。
是否有可能检测到与客户端断开连接(例如关闭 Web 浏览器中的选项卡)。我想这样做,因为断开连接后客户端将无法看到计算结果,所以我可以杀死应用程序并释放服务器上的一些 RAM。
感谢您的任何帮助或建议。
我的 C++ 应用程序有非常原始的 Web 前端。客户端(网络浏览器)进入 php 站点并用参数填写表单。比(在提交后)php 调用exec并且应用程序完成它的工作。应用程序可以工作超过一分钟,并且需要大量的 RAM。
是否有可能检测到与客户端断开连接(例如关闭 Web 浏览器中的选项卡)。我想这样做,因为断开连接后客户端将无法看到计算结果,所以我可以杀死应用程序并释放服务器上的一些 RAM。
感谢您的任何帮助或建议。
只要 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
. 我怀疑您将需要为此pcntl
安装,因为 PHP 手册表明常量是由扩展定义的 - 尽管我从来没有安装过一个没有另一个,所以我不确定任何一种方式。posix
SIGxxx
pcntl