當前位置: 首頁> 最新文章列表> 使用time_nanosleep 實現精確的睡眠時間控制

使用time_nanosleep 實現精確的睡眠時間控制

gitbox 2025-05-28

在PHP 中,我們經常需要讓程序暫停一段時間,這在處理輪詢、定時任務或限速操作時非常常見。通常,大家會使用sleep()函數來實現這一目的,但sleep()的時間單位是秒,無法滿足對毫秒甚至納秒級別的精確控制需求。這時,PHP 提供了time_nanosleep()函數,能讓你以秒和納秒的精度來控制暫停時間。

什麼是time_nanosleep()

time_nanosleep()是PHP 5.0.0 及以上版本中提供的函數,用來讓當前進程暫停指定的秒數和納秒數。相比sleep()只能精確到秒, time_nanosleep()允許你更靈活地控制暫停時間。

函數定義如下:

 bool time_nanosleep(int $seconds, int $nanoseconds)
  • $seconds :暫停的秒數,整數。

  • $nanoseconds :暫停的納秒數,整數,範圍為0 到999,999,999。

如果暫停成功,函數返回true ,如果中途被信號打斷,則返回一個包含剩餘時間的數組。

使用示例

下面是一個簡單的例子,演示如何用time_nanosleep()暫停1 秒又500 毫秒(即1.5 秒):

 <?php
echo "開始時間:" . microtime(true) . PHP_EOL;

$seconds = 1;
$nanoseconds = 500000000; // 500 毫秒 = 500,000,000 納秒

if (time_nanosleep($seconds, $nanoseconds)) {
    echo "睡眠結束時間:" . microtime(true) . PHP_EOL;
} else {
    echo "睡眠被中斷" . PHP_EOL;
}
?>

運行結果會顯示兩次時間戳,時間差約為1.5 秒。

處理中斷情況

如果time_nanosleep()被系統信號中斷,會返回一個數組,裡麵包含剩餘的秒數和納秒數。你可以根據返回值重新調用time_nanosleep()來繼續睡眠。示例如下:

 <?php
$seconds = 2;
$nanoseconds = 0;

while (true) {
    $result = time_nanosleep($seconds, $nanoseconds);
    if ($result === true) {
        echo "睡眠完成" . PHP_EOL;
        break;
    } elseif (is_array($result)) {
        echo "睡眠被中斷,剩餘時間:{$result['seconds']}秒 {$result['nanoseconds']}納秒" . PHP_EOL;
        $seconds = $result['seconds'];
        $nanoseconds = $result['nanoseconds'];
    } else {
        echo "睡眠失敗" . PHP_EOL;
        break;
    }
}
?>

這種寫法確保程序能夠在被信號打斷後繼續完成預定的睡眠時間。

結合HTTP 請求的使用場景示例

假設你想實現一個請求限速的功能,每次請求之間暫停200 毫秒,可以結合curl發送請求,使用time_nanosleep()來精準控制間隔時間。以下是示例代碼:

 <?php
$urls = [
    "https://gitbox.net/api/data1",
    "https://gitbox.net/api/data2",
    "https://gitbox.net/api/data3",
];

foreach ($urls as $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($ch);
    if (curl_errno($ch)) {
        echo "請求失敗:" . curl_error($ch) . PHP_EOL;
    } else {
        echo "請求成功:" . substr($response, 0, 50) . "..." . PHP_EOL;
    }
    curl_close($ch);

    // 暫停 200 毫秒
    time_nanosleep(0, 200000000);
}
?>

這段代碼依次請求三個接口,每次請求後暫停200 毫秒,從而避免請求過於頻繁。

總結

  • time_nanosleep()允許你以秒和納秒的精度讓PHP 程序暫停。

  • 它比傳統的sleep()usleep()更加靈活,適合對時間控制精度要求高的場景。

  • 需要注意處理信號中斷的情況,保證程序邏輯的健壯性。

  • 在需要限速、間隔控製或精細調度時, time_nanosleep()是一個非常實用的函數。

通過合理運用time_nanosleep() ,可以讓你的PHP 應用在時間控制上更加精準和高效。