1

我敢肯定,类似的问题已经被一遍又一遍地回答了。如果是,那么我在错误的方向上搜索并为此道歉。

我的问题:我正在编写一个在后台运行的进程的网页。我正在谈论的过程是一个 R 脚本,运行时间很长,可能需要几天。当进度开始时,它就这样开始了。

exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));

我想跟踪进程是否仍在运行。这样,当用户检查时,他会收到有关它已完成或未完成的消息。当用户在再次登录或在页面上执行其他操作之后选择他上传到服务器的输入文件时,跟踪开始和停止。我还希望它在进程完成时更新页面,以便页面发生变化,以防他只是看着它。

我有两种可能。我可以通过进程 ID 或是否生成输出文件来检查它。

我试过了

while(is_process_running($ps)){ ob_flush(); flush(); sleep(1); }

这有点像,除了页面上的所有其他功能冻结。那是我的 is_process_running($ps) 函数。

function is_process_running($PID){ exec("ps $PID", $ProcessState); return(count($ProcessState) >= 2); }

我真正需要的是在后台运行的另一个进程检查第一个进程是否仍在运行,如果没有,则在第一个进程完成时刷新页面。你会怎么做?如果您需要更多信息,请告诉我。非常感谢所有帮助。

4

2 回答 2

1

通过 symcbean 的回答,我能够解决它。我的 javascript 代码在下面,可能对面临同样问题的人有用。我也愿意改进。我仍然认为自己是初学者。

function loadXMLDoc(){
    var xmlhttp;
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }else{// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlhttp;
}
function start(file,time){
    var xmlhttp = loadXMLDoc();
    if(lines == 0){
        timer = setInterval(function(){sendRequest(xmlhttp,file)},time);
    }
}
function sendRequest(xmlhttp,file){
    xmlhttp.open("POST",file,true);
    xmlhttp.send()
    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200 && xmlhttp.responseText != ""){
            var text = xmlhttp.responseText;
            var splitted = text.split("\n");
            var length = splitted.length
            if(splitted[length-2]=="finished"){
                refresh_page();
                clearInterval(timer);
                lines = 0;
            }                   
        }
    }
}

使用文件路径和应该检查更改的时间间隔调用 start 方法。请注意我没有发布的刷新页面方法,但这只是您想要在页面上刷新的任何内容。当文件中的最后一行显示完成时,页面会刷新。我包含了 line 变量来检查进程是否已经启动。我还没有完全测试代码,但到目前为止它正在做我想做的事情。

于 2012-08-02T23:36:14.343 回答
0

首先,您启动进程的方式存在许多问题 - 它确实需要位于与启动它的 PHP 不同的进程组中。

至于检查它的状态,你不希望 PHP 的东西在 http 连接结束时停留很长时间。此外,让网络服务器按需将内容刷新到浏览器并让浏览器逐步呈现它是非常困难的——而且很脆弱。即使你让它在一个浏览器/网络服务器组合上工作,它也不太可能在另一个上工作。

使用 Ajax 轮询一个简单的脚本,该脚本报告进程状态/进度。

于 2012-08-01T22:59:18.770 回答