PHP Conference Japan 2024

usleep

(PHP 4, PHP 5, PHP 7, PHP 8)

usleep以微秒为单位延迟执行

描述

usleep(int $microseconds): void

将程序执行延迟指定的微秒数。

参数

microseconds

以微秒为单位的暂停时间。 一微秒等于百万分之一秒。

注意: 大于 1000000 的值(即睡眠超过一秒)可能不受操作系统支持。 请改用 sleep()

注意: 睡眠时间可能会略微延长(即可能长于 microseconds),这可能是由于任何系统活动或处理调用所花费的时间,或者系统计时器的粒度造成的。

返回值

不返回任何值。

示例

示例 #1 usleep() 示例

<?php

// 当前时间
echo (new DateTime('now'))->format('H:i:s.v'), "\n";

// 等待 2 毫秒
usleep(2000);

// 返回!
echo (new DateTime('now'))->format('H:i:s.v'), "\n";

// 等待 30 毫秒
usleep(30000);

// 再次返回!
echo (new DateTime('now'))->format('H:i:s.v'), "\n";

?>

以上示例将输出

11:13:28.005
11:13:28.007
11:13:28.037

参见

添加注释

用户贡献的注释 10 条注释

Docey
17 年前
sleep 和 usleep 的理念是,通过让 CPU 运行一些空闲周期,以便其他程序可以运行一些自己的周期。这导致更好的响应时间和更低的整体系统负载。因此,如果您必须等待某些内容,请休眠几秒钟,而不是在完全不执行任何操作(除了等待)时占用 CPU。
m dot prowler at gmail dot com
9 年前
在 MacOS X 和 Linux 上,usleep() 调用似乎会消耗 CPU 周期,而 sleep() 和 time_nanosleep() 则不会。在 PHP 5.3.29 和 5.5.29 上也是如此。

我使用了一个循环,其中只包含对 sleep/usleep/time_nanosleep 的调用,并将它们全部与一个空循环进行了比较。显然,空循环消耗了 99% 的 CPU,sleep 使用了 0%,usleep 在 1000ms 时使用了 3%,在 100ms 时使用了 6%,time_nanosleep 在 500ms 和 1000ms 时都使用了 0%。
gizmo at aoaforums dot com
18 年前
需要注意的是,Windows 机器在使用 kernel32.dll 中的 Sleep() 函数时,分辨率为 10 毫秒或 15 毫秒(取决于芯片组实现和使用的 HAL)。这意味着您的平均误差将为 5 或 7.5 毫秒。除非您确实需要休眠的时间小于 Windows 提供的粒度,否则这通常不是问题。
busby at edoceo dot com
21 年前
应该注意的是,循环非常快以创建延迟的函数也会在执行循环时消耗 100% 的 CPU。尝试创建一个循环 100000 次的虚拟循环,观察它如何使您的机器窒息。如果您确实需要 usleep(),请不要使用 Windows。
gmc at serveisw3 dot net
19 年前
如果您使用的是 Windows,那么如果您确实需要使用 usleep,则可能会遇到麻烦。

使用 fsockopen 的 Bernie 的微延迟函数无法正常工作,并且 fclose 帮助不大。

我不知道网络连接是否出现异常,但我知道它确实不起作用,因为您已对其进行了超过 2000-3000 次调用,因此在“长期运行”的 PHP 脚本中它不是一个可靠的解决方案,或者这些是我的 PHP 和 PHP-GTK 应用程序中微延迟函数的问题。

虽然应该找到其他解决方案,并且在谷歌搜索了一下后我找到了一个 WinAPI 函数:Sleep。

所以,我使用这段代码,它对我的工作很好,您可以获得毫秒级的精度,但更重要的是,它适用于长期运行的脚本,当然,它不会浪费任何 CPU 周期。

dl('php_w32api.dll');

$GLOBALS['win32api'] =& new win32;

// Windows 和 PHP4 的 USleep 替代方案
$GLOBALS['win32api']->registerfunction("long Sleep (long dwMillisecods) From kernel32.dll");

// 现在您可以在脚本中的任何地方调用该函数:$GLOBALS['win32api']->Sleep(milliseconds);

for ($msec = 2000; $msec > 0; $msec = $msec - 125) {
echo "Hi. Next one in $msec msec.\n";
$GLOBALS['win32api']->Sleep($msec);
}
Bertie
21 年前
关于发布的 microdelay() 代码(使用 fsockopen)的一个警告 - 如果您在循环中使用它以短时间延迟,您将很快耗尽套接字/套接字缓冲区空间。然后您的网络连接就会变得非常奇怪……

Rasmus Schultz
18 年前
我花了几天时间尝试为 Windows 创建一个可靠的 usleep() 替代函数。

我只能提供这些。

正如其他人已经评论的那样,下面使用的 gettimeofday() 方法毫无用处 - PHP 将使用所有可用的 CPU 功率来执行无用操作。

fsockopen() 方法显然也毫无用处 - 正如其他人评论的那样,原始帖子中缺少一个 fclose(),但这显然不能解决问题。在调用该函数大约 50 次左右后,fsockopen() 会立即返回,没有任何延迟 - 并且在 Windows 中观察进程监视器,您随后可以看到该进程占用越来越多的内存,直到最终 PHP 在达到最大值时中止(或崩溃)。

win32api 方法也不行...在调用 Sleep 函数几百次后(在此期间,由于某处的内存泄漏,内存使用量也会每次增加),PHP 将导致异常,并且 Windows 将终止它。

我放弃了 - 我认为在 PHP 4 下没有可行的解决方案来解决此问题。

如果您需要此函数,请将您的项目升级到 PHP 5。

或者使用 sleep() 函数进行 1 秒的延迟。

不幸的是,这些似乎是您唯一的选项...
Mike at SevenCode dot com
17 年前
伙计,你为这段代码片段真是太棒了。它像魅力一样工作。我只是想指出一些事情并提供我自己的改进。

1. 如果您像我一样,您可能想知道为什么套接字必须在每次调用时都重新创建,以及为什么不能只创建一个静态套接字。这是因为 socket_select 假设您正在传递一个指针,并且将在返回时更改变量以反映实际更改的套接字。

2. 我无论如何也弄不清楚为什么 socket_select 没有定义。这是因为您没有在 php.ini 中启用正确的扩展。

好的,这是我的一点改进。我真正做的只是为套接字使用一个静态变量,以避免在每次调用此函数时都创建一个全新的套接字。我不确定套接字创建是否会导致像此处报告的其他问题一样导致程序崩溃,但如果您问我,谨慎总比后悔好。

function Sleeper($mSec)
{
// 对于像我这样的傻瓜,他们花了 5 分钟
// 想知道为什么 socket_create 没有定义
if(!function_exists('socket_create')){
die("请启用扩展 php_sockets.dll");
}

// 因此套接字仅创建一次
static $socket=false;
if($socket===false){
$socket=array(socket_create(AF_INET,SOCK_RAW,0));
}
$pSock=$socket;

// 计算时间
$uSex = $mSec * 1000;

// 执行等待
socket_select($read=NULL,$write=NULL,$pSock,0,$uSex);

// 强迫症
return true;
}
dave at techweavers dot net
23 年前
要监控脚本的 CPU 使用情况并避免任何讨厌的 CPU 占用循环,您可以使用此函数(不适用于 Windows 或安全模式)我知道它在 FreeBSD 上有效
function phpmon($max)
{
$cmd = `ps -Unobody -r -o%cpu`;
$lines = explode("\n", $cmd);
$usage = substr($lines[1], 0, strpos($lines[1], "."));
$sleeprate = 500;
while ($usage >= $max)
{
$cmd = `ps -Unobody -r -o%cpu`;
$lines = explode("\n", $cmd);
$usage = substr($lines[1], 0, strpos($lines[1], "."));
usleep($sleeprate);
}
}

phpmon($MAX);

其中 $MAX 是您希望进程消耗的最大 CPU。如有任何改进/建议,请发送电子邮件给我。

我注意到这会消耗大量系统 CPU(至少在我的有限测试中),可能是由于所有系统调用或我用来测试脚本有效性的巨大数学函数。
septerrianin at mail dot ru
6 年前
请注意,此函数存在开销!

示例
<?php
for ($i = 0; $i < 1000000; ++$i)
{
usleep(1);
}
?>

此代码块在我的服务器上大约运行 70 秒。
脚本每个 usleep() 函数调用大约需要 70 微秒。
To Top