当前位置: 首页> 最新文章列表> 利用 time_nanosleep 创建 PHP 计时器功能

利用 time_nanosleep 创建 PHP 计时器功能

gitbox 2025-05-28

在 PHP 中实现计时器功能,有多种方式可以选择。time_nanosleep 函数是一个非常精准的睡眠函数,它允许脚本暂停执行指定的秒数和纳秒数,从而可以用来实现高精度的计时器。本文将详细介绍如何使用 time_nanosleep 函数来创建一个简单的计时器。

什么是 time_nanosleep

time_nanosleep 函数用来让当前执行的脚本暂停指定的时间,时间的单位包括秒(seconds)和纳秒(nanoseconds)。其语法如下:

bool time_nanosleep(int $seconds, int $nanoseconds)
  • $seconds:暂停的秒数,非负整数。

  • $nanoseconds:暂停的纳秒数,范围是 0 到 999,999,999。

函数返回 true 表示正常休眠完毕,失败时返回 false,或者触发错误。

使用场景

time_nanosleep 非常适合需要精确控制等待时间的场景,比如:

  • 实现高精度计时器

  • 控制执行频率

  • 避免 CPU 空转,减少资源浪费

实现一个简单的计时器示例

下面的例子中,我们将实现一个计时器,每隔指定的毫秒数输出一次时间戳,直到达到总时间。

<?php

/**
 * 简单计时器函数,按指定间隔执行任务
 * 
 * @param int $interval_ms 间隔时间,单位毫秒
 * @param int $total_duration_ms 总计时长,单位毫秒
 */
function simple_timer(int $interval_ms, int $total_duration_ms)
{
    $start_time = microtime(true);
    $elapsed = 0;

    while ($elapsed < $total_duration_ms / 1000) {
        // 计算睡眠秒和纳秒
        $seconds = intdiv($interval_ms, 1000);
        $nanoseconds = ($interval_ms % 1000) * 1000000;

        // 睡眠指定时间
        time_nanosleep($seconds, $nanoseconds);

        // 输出当前时间戳和已运行时间
        $current_time = microtime(true);
        $elapsed = $current_time - $start_time;
        echo "Elapsed: " . round($elapsed, 3) . " seconds\n";
    }

    echo "计时结束!\n";
}

// 每隔 500 毫秒执行一次,持续 5 秒
simple_timer(500, 5000);

代码解析

  • 使用 microtime(true) 获取高精度当前时间。

  • 循环内调用 time_nanosleep 让脚本暂停指定时间。

  • 计算已运行时间并打印。

  • 循环直到达到设定的总时长。

注意事项

  • time_nanosleep 可能被信号中断,如果中断,函数会返回 false 并触发警告,可以用 pcntl 函数捕获信号以保证稳定。

  • 纳秒的精度取决于操作系统,不是所有系统都支持非常精细的纳秒级别睡眠。

  • 在一些环境中,usleeptime_nanosleep 的精度和效果可能差别不大。

结合远程资源示例

假如你需要通过 PHP 访问远程接口,结合计时器做周期请求,可以用如下代码示例:

<?php

function fetch_data_periodically($url, $interval_ms, $times)
{
    for ($i = 0; $i < $times; $i++) {
        // 发送请求
        $response = file_get_contents($url);
        echo "Response #$i: " . substr($response, 0, 50) . "...\n";

        // 睡眠
        $seconds = intdiv($interval_ms, 1000);
        $nanoseconds = ($interval_ms % 1000) * 1000000;
        time_nanosleep($seconds, $nanoseconds);
    }
}

$url = "https://gitbox.net/api/data";
fetch_data_periodically($url, 1000, 3);

这段代码每隔 1 秒请求一次 gitbox.net 上的接口,连续执行 3 次。