我使用proc_open()
打开流程,然后usleep()
打开一段时间,然后检查流程的状态。如果该过程仍在运行,那么我proc_terminate()
。
问题是当我使用proc_terminate()
脚本继续而没有等待进程终止(这是正常的), 但是即使经过很多时间也没有终止进程。
该过程是.exe
文件,首先将hello
打印到标准输出,然后进入无限循环。
我的PHP脚本:
<pre>
<?php
$descriptorspec = array(
1 => array('pipe', 'w')
);
$process = proc_open("C:/wamp/www/my-project/run.exe", $descriptorspec, $pipes);
if (is_resource($process)) {
usleep(2.5*1000000); // wait 2.5 secs
$status = proc_get_status($process);
if ($status['running'] == true) {
proc_terminate($process);
echo "Terminated\n";
} else {
echo "Exited in time\n";
echo "EXIT CODE : {$status['exitcode']}\n";
echo "OUTPUT :\n";
while (!feof($pipes[1]))
echo fgets($pipes[1]);
fclose($pipes[1]);
proc_close($process);
}
}
?>
</pre>
我编译此C ++文件并获取.exe
:
#include <iostream>
using namespace std;
int main() {
cout << "hello";
while (1);
return 0;
}
有人知道为什么会这样吗? :(
答案 0 :(得分:2)
proc_terminate()
在Windows上运行不佳。
一个好的解决方法是调用taskkill
命令。
function kill($process) {
if (strncasecmp(PHP_OS, 'WIN', 3) == 0) {
$status = proc_get_status($process);
return exec('taskkill /F /T /PID '.$status['pid']);
} else {
return proc_terminate($process);
}
}
答案 1 :(得分:0)
proc_terminate
实际上并不终止进程,它会向进程发送SIGTERM
信号,要求它自行终止。
我认为问题是你的测试可执行文件没有监听SIGTERM
信号,所以它只是被忽略了。
在POSIX系统上,您可以使用第二个参数发送SIGKILL
,这实际上会要求操作系统终止该过程,这样可能会更好。在Windows上,我不知道这会做什么,如果有的话。
但是这个过程应该是处理信号。您可以轻松地向您的exe添加信号处理程序以进行测试:
#include <csignal>
#include <iostream>
#include <thread>
using namespace std;
void signal_handler(int signal)
{
cout << "received SIGTERM\n";
exit(0);
}
int main()
{
// Install a signal handler
std::signal(SIGTERM, signal_handler);
cout << "starting\n";
while (1)
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
请注意同时添加sleep_for
,以便exe不占用100%的CPU。
在here评论中还讨论了使用posix_kill()
来杀死进程及其子进程的问题,如果以上内容对您不起作用的话。