52

我刚刚查看了sleep().

你会在哪里使用这个功能?

是否可以让 CPU 在昂贵的功能中休息一下?

有什么常见的陷阱吗?

4

13 回答 13

51

它发现使用的一个地方是创建一个延迟

假设您已经构建了一个使用curl/file_get_contents获取远程页面的爬虫。现在你不想在短时间内用太多的请求轰炸远程服务器。因此,您在连续请求之间引入了延迟。

sleep以秒为单位接受参数,它的朋友usleep以微秒为单位接受参数,在某些情况下更合适。

于 2010-10-14T06:53:07.033 回答
33

另一个例子:您正在运行某种大量使用资源的批处理过程。也许您正在浏览 9,000,000 本书的数据库并更新其中大约 10%。该过程必须在一天的中间运行,但是要完成的更新太多,运行批处理程序会将数据库服务器拖到其他用户的爬网中。

因此,您将批处理过程修改为提交 1000 次更新,然后sleep在 5 秒内让数据库服务器有机会完成处理来自已备份的其他用户的任何请求。

于 2010-10-15T03:45:55.020 回答
25

这是我sleep在一个项目中使用的片段:

foreach($addresses as $address)
{
  $url = "http://maps.google.com/maps/geo?q={$address}&output=json...etc...";
  $result = file_get_contents($url);
  $geo = json_decode($result, TRUE);

  // Do stuff with $geo

  sleep(1);
}

在这种情况下sleep,帮助我防止被谷歌地图阻止,因为我向服务器发送了太多请求。

于 2010-10-14T06:58:53.920 回答
10

我知道的老问题,但使用 u/sleep 的另一个原因可能是在您编写安全/加密代码时,例如身份验证脚本。几个例子:

  1. 您可能希望通过故意使登录脚本变慢来降低潜在暴力攻击的有效性,尤其是在几次尝试失败之后。
  2. 此外,您可能希望在加密期间添加人为延迟以减轻定时攻击。我知道你用 PHP 这样的语言编写如此深入的加密代码的可能性很小,但我认为仍然有效。

编辑

使用 u/sleep 对抗定时攻击并不是一个好的解决方案。您仍然可以在定时攻击中获取重要数据,您只需要更多样本来过滤掉 u/sleep 添加的噪声。

您可以在以下位置找到有关此主题的更多信息:随机睡眠可以防止定时攻击吗?

于 2013-10-19T20:58:00.697 回答
2

这有点奇怪……文件传输限制。

在我们很久以前运行的文件传输服务中,文件由 10Mbps 上行链路服务器提供。为了防止网络瘫痪,下载脚本会跟踪有多少用户同时下载,然后计算每个用户每秒可以发送多少字节。它会发送这个数量的一部分,然后睡一会儿(我认为是 1/4 秒)然后发送更多......等等。

这样,服务器以大约 9.5Mbps 的速度连续运行,没有上行链路饱和问题……并且始终动态调整下载速度。

我不会这样做,或者在 PHP 中,现在......但它当时工作得很好。

于 2017-03-28T21:58:58.533 回答
1

您可以使用 sleep 来暂停脚本执行......例如延迟服务器端的AJAX调用或实现观察者。您还可以使用它来模拟延迟。

我也用它来延迟 sendmail() & co。.

有人使用 sleep() 来防止 DoS 和登录 brutefoces,我不同意,因为您需要添加一些检查以防止用户多次运行。

检查也usleep

于 2010-10-14T07:02:45.143 回答
1

我最近在使用 Google 的 Geolocation API 时不得不使用它。循环中的每个地址都需要调用 Google 的服务器,因此需要一些时间来接收响应。我曾经usleep(500000)给所有涉及的事情足够的时间。

于 2011-10-23T17:01:35.213 回答
1

我通常不会将它用于提供网页,但它对命令行脚本很有用。

$ready = false;
do {
  $ready = some_monitor_function();
  sleep(2);
} while (!$ready);
于 2012-12-13T19:59:22.750 回答
1

超级老帖子,但我想我也会发表评论。我最近不得不检查一个运行时间很长的进程,它创建了一些文件。所以我制作了一个迭代 cURL 函数的函数。如果我要查找的文件不存在,我会休眠 php 文件,然后再检查一下:

function remoteFileExists() {
    $curl = curl_init('domain.com/file.ext');

    //don't fetch the actual page, you only want to check the connection is ok
    curl_setopt($curl, CURLOPT_NOBODY, true);

    //do request
    $result = curl_exec($curl);

    //if request did not fail
    if ($result !== false) {
        //if request was ok, check response code
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);  

        if ($statusCode == 404) {
              sleep(7);
              remoteFileExists();
        }
        else{
            echo 'exists'; 
        }
    }

    curl_close($curl);

}

echo remoteFileExists();
于 2013-08-17T07:43:16.800 回答
1

另一种使用它的方法:如果你想每分钟更频繁地执行一个 cronjob。我为此使用以下代码:

sleep(30);
include 'cronjob.php';

我每分钟调用这个文件和 cronjob.php。

于 2016-12-06T19:54:04.670 回答
0

它的应用之一是,如果我通过脚本向 100 多个客户发送邮件,那么此操作最多需要 1-2 秒,因此大多数网站(如 hotmail 和 yahoo)都将其视为垃圾邮件,因此为避免这种情况,我们需要使用每封邮件后都会有一些延迟执行。

于 2014-09-19T13:17:08.157 回答
0

其中包括:您正在测试一个发出异步请求(AJAX 调用、延迟图像加载……)的 Web 应用程序

您正在本地对其进行测试,因此响应是即时的,因为只有一个用户(您)并且没有网络延迟。

使用sleep可让您查看/测试 Web 应用程序在负载和网络导致请求延迟时的行为方式。

于 2016-10-25T19:10:06.233 回答
0

一个快速的伪代码示例,说明您可能不想为单个事件收到数百万封警报电子邮件,但您希望脚本继续运行。

  if CheckSystemCPU() > 95  
        SendMeAnEmail()
        sleep(1800)
  fi
于 2016-11-22T02:24:05.087 回答