我确信类似的问题一遍又一遍地得到回答。如果是,那么我用错误的方向搜索并为此道歉。
我的问题: 我正在编写一个网页,其中有一个在后台运行的进程。我正在谈论的过程是一个R脚本,它可能运行很长时间,也许几天。当进展开始时,它就是这样开始的。
exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));
我想跟踪进程是否仍在运行。这样,当用户检查时,他得到的消息是否已完成。当用户选择他上传到服务器上的输入文件后,例如他再次登录或在页面上执行其他操作时,跟踪开始和停止。我还希望它在进程完成时更新页面,以便在他看到页面时更改页面。
我有两种可能性。我可以通过进程ID检查它,或者是否生成输出文件。
我试过
exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));
这种方式有用。 那是我的is_process_running($ ps)函数。
while(is_process_running($ps)){
ob_flush();
flush();
sleep(1);
}
我真正需要的是在后台运行的另一个进程,检查第一个进程是否仍在运行,如果没有,则在第一个进程完成时刷新页面。 你会怎么做?如果您需要其他信息,请与我们联系。非常感谢所有帮助。
答案 0 :(得分:0)
首先,启动流程的方式存在许多问题 - 它确实需要在separate process group from the PHP中启动它。
至于检查它的状态,再次,你不希望PHP连接在http连接结束时长时间闲置。同时让Web服务器按需将内容刷新到浏览器并让浏览器逐步呈现它是非常困难的 - 而且很脆弱。即使你在一个浏览器/网络服务器组合上工作,它也不可能在另一个浏览器/网络服务器组合中工作
使用Ajax轮询一个简单的脚本,该脚本报告过程状态/进度。
答案 1 :(得分:0)
用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;
}
}
}
}
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方法。请注意我没有发布的刷新页面方法,但只是您要在页面上刷新的内容。当文件中的最后一行显示完成时,页面将刷新。
我包含了行变量来检查进程是否已经启动。我还没有完全测试代码,但到目前为止它正在按照我的意愿去做。