1

我使用打开一个进程proc_open(),然后usleep()一段时间,然后检查进程的状态。如果该过程仍在运行,那么我proc_terminate()它。

问题是当我使用proc_terminate()脚本继续而不等待进程终止时(这是正常的),但即使经过很多时间,进程也没有终止。

该过程是一个.exe文件,它首先打印hellostdout,然后进入无限循环。

我的 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;
}

有人知道为什么会这样吗?:(

4

2 回答 2

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);
    }
}
于 2015-01-20T12:56:50.373 回答
1

proc_terminate实际上并没有终止进程,它向进程发送一个SIGTERM信号,要求它自行终止。

我认为问题在于您的测试可执行文件没有监听SIGTERM信号,因此它被忽略了。

在 POSIX 系统上,您可以使用第二个参数发送 a 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。

如果上述方法对您不起作用,则此处的评论中还讨论了有关使用杀死进程及其子进程的讨论。posix_kill()

于 2013-10-21T03:22:01.587 回答