PHP父/子定时通信

时间:2011-12-31 12:48:58

标签: php fork

我正在开发一个应用程序,它允许我登录远程telnet服务器并监控统计信息。问题是telnet服务器的最小刷新率为10秒,刷新率根据服务器负载略有不同(报告本身具有此刷新率,而不是服务器)。我需要这个系统的前端比每10秒更新一次(最少5秒)。我有点能够通过分叉来实现这一点,但最终时间同步(这是一个渐进的过程,我假设是由于远程服务器负载)。

子代码:(我已经删除了很多与应用程序登录和访问报告有关的代码,但它基本上是按键通过7个菜单进入刷新的页面 - 如果需要,我可以包括):

// 1 - Telnet Handshaking and initial screen load
$sHandshaking = '<IAC><WILL><OPT_BINARY><IAC><DO><OPT_BINARY><IAC><WILL><OPT_TSPEED><IAC><SB><OPT_TSPEED><IS>38400,38400<IAC><SE>';
// 2-4 - Keypresses to get to report (login, menus, etc. - Removed)

// Loop and cache
while(1){
    //  4 - View Report
    $oVT100->listen(); 
    $reference = $temp;
    $screen = $oVT100->getScreenFull();
    if(empty($screen)){
        Failed:
        echo "FAILED";
        file_put_contents($outFile,array('html'=>"<div class=\"header\"><font color='red'>Why are things always breaking?!<font color='red'></div>"));
        goto restartIt; // If screen does not contain valid report, assume logout and start at top
    }else{
        $screen = parseReport($oVT100->getScreenFull());
        $temp = json_decode($screen);
        // Check old report file, if different save, else sleep a bit
        $currentFile = file_get_contents($outFile);
        if($screen !== $currentFile){
            file_put_contents($outFile,$screen);
            sleep(5);
        }else{
            sleep(1);
            //usleep(500000);
        }
    }
}

正如您在上面的孩子的代码中看到的那样,它会在报告中记录无限循环。然后它将屏幕写入缓存文件(如果它与现有文件不同)。作为刷新问题的一个肮脏的解决方法,我写了一个父的fork:

$pids = array();

for($i = 0; $i < 2; $i++) {
    sleep(5);
  $pids[$i] = pcntl_fork();

  if(!$pids[$i]) {
    require_once(dirname(__FILE__).'/checkQueue.php');
    exit();
  }

}

for($i = 0; $i < 2; $i++) {
  pcntl_waitpid($pids[$i], $status, WUNTRACED);
}

我立刻注意到了时间偏移,不得不产生三个孩子,而不是两个,以保持在5秒内;但时间安排了几天。最终,所有的孩子都在同时更新文件,我不得不重新启动父文件。什么是监视子进程的最佳解决方案,以便我保持不到五秒的刷新间隔?

[编辑] 这不是运行日志,它是包含呼叫中心当前呼叫统计信息的文件。缓存文件中的数据在任何时候都必须不小于5秒,但最终所有子节点几乎同时同步并写入日志。问题不在于本地文件,它与远程服务器响应时间不一致,最终导致子进程同时运行获取报告。

1 个答案:

答案 0 :(得分:0)

我希望有一个更好的解决方案,但这就是我如何解决它 - 我觉得因为没有考虑到这一点而感到愚蠢:

$currentFile = file_get_contents($outFile);
if($screen !== $currentFile){
    if(time()-filemtime($outFile) > 2){
        file_put_contents($outFile,$screen);
        sleep(5);
    }else{
        echo "Failed, sleeping\r";
        sleep(2);
    }
}else{
    sleep(1);
    //usleep(500000);
}

基本上,我检查缓存文件的文件写入时间,如果不到2秒,则休眠并重新执行循环。我有点希望在父应用程序中包含一个解决方案,但我猜这有效......