當前位置: 首頁> 最新文章列表> 利用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 次。