php while循环高cpu使用率

时间:2013-12-25 01:20:27

标签: php loops

我有一个ipcamera,/video/feed/1.jpg(作为ramdrive安装)以大约5fps写入。如果连接不良,有时这可能小于1 fps。 我试图每500毫秒在浏览器中更新一次图像,但我有两个目标:

  • 如果相机尚未更新,我不希望服务器输出相同的图像。
  • 如果相机尚未完成写入,我不想输出部分图像。

我尝试通过创建映像的md5并将其存储在会话中来实现此目的,如果在下一个浏览器请求中md5未更改,则服务器将循环直到md5不同。服务器也将循环,直到md5与之前加载的时间匹配,这样我就可以确定相机已经完成了图像的创建。

这个过程按预期工作,但是cpu的使用率已经达到顶峰,所以我正在寻找有关改进的建议。

test.php的

<?php
session_start();
$imgFile = '/video/feed/1.jpg';
$lastImg = $_SESSION['image'];
$imgMd5 =0;
do {
    sleep(.2);
    $img = (file_get_contents($imgFile));
    $lastMd5 = $imgMd5;
    $imgMd5 = md5($img);
    if ($lastMd5 != $imgMd5) {
    continue;
    }
    if ($imgMd5 != $lastImg) {
        break;
    }
} while (0 == 0);
header("Content-type: image/jpg");
$_SESSION['image'] = md5($img);
echo $img;
exit;
?>

JS

      <script>
            img = new Image
            function f() {
                img.src = "test.php?rnd=" + Date.now();
                img.onload = function() {
                    feed.src = img.src;
                    setTimeout(function() {
                        f();
                   }, 500);
                };
                img.onerror= function(){
                    setTimeout(function() {
                        f();
                    }, 500);
                };
            }
            f();
        </script>

2 个答案:

答案 0 :(得分:2)

我真正需要的是usleep(200000)

sleep(.2)没有像我预期的那样发挥作用。

答案 1 :(得分:0)

不是使用MD5哈希来检查文件是否发生了变化,而是使用上次修改的时间应该比每次计算MD5哈希要少(但由于某种原因在我的Windows上)机器它仍然使用大量的CPU,所以我不确定),你可以尝试我的代码:

<?php

session_start();

$path = "/video/feed/1.jpg";

if (isset($_SESSION["lastmodified"])) { // if there's no previous timestamp, do not execute all of this and jump straight into serving the image.
    while ($_SESSION["lastmodified"] == filemtime($path)) {
            sleep(1); // sleep while timestamp is the same as before.
            clearstatcache(); // PHP caches file informations such as last modified timestamp, so we need to clear it each time or we'll run into an infinite loop.
        }
}

$_SESSION["lastmodified"] = filemtime($path); // set the new time variable.

header("Content-type: image/jpg");
echo file_get_contents($path);

?>

编辑:您可以让您的网络服务器通过直接提供RAMdisk目录来处理所有这些,设置适当的缓存控制标头并使用meta refresh标记每秒重新加载页面。当页面重新加载时,网络服务器将仅在它存在时提供新图像(如果不存在,它将仅返回“未修改”到浏览器,并且它将从其缓存中提供最后一个图像。)