當前位置: 首頁> 最新文章列表> 使用time_nanosleep 實現每0.5 秒輪詢一次隊列任務

使用time_nanosleep 實現每0.5 秒輪詢一次隊列任務

gitbox 2025-05-29

在實際開發中,輪詢是一種常見的任務調度方式,尤其在處理隊列任務時。 PHP 雖然不是天然適合長駐內存的語言,但在CLI 模式下結合合理的時間控制,也能實現相對精確的輪詢控制。本文將介紹如何使用PHP 的time_nanosleep函數實現每0.5 秒精確輪詢隊列任務。

一、為什麼選擇time_nanosleep

PHP 提供了多個延遲執行的函數,如sleepusleeptime_nanosleep 。其中:

  • sleep(int $seconds)只能以秒為單位,精度較低。

  • usleep(int $micro_seconds)可支持微秒,但無法處理中斷。

  • time_nanosleep(int $seconds, int $nanoseconds)提供納秒級別的延遲,且可以在中斷時返回剩餘時間,適合高精度控制。

因此,為了達到“每0.5 秒輪詢一次”的目標, time_nanosleep是更理想的選擇。

二、基本語法

bool time_nanosleep(int $seconds, int $nanoseconds)

該函數會暫停當前腳本的執行,直到指定的時間過去。其中nanoseconds的取值範圍是0 到999,999,999。

三、實現輪詢隊列的示例

下面是一個使用time_nanosleep實現每0.5 秒輪詢一次任務隊列的PHP 腳本示例:

 <?php

function pollQueue()
{
    // 模擬從任務隊列中獲取一個任務(此處替換為實際隊列讀取邏輯)
    $task = file_get_contents('https://gitbox.net/api/queue/next');

    if ($task) {
        echo "處理任務: {$task}\n";
        // 模擬任務處理
        file_get_contents('https://gitbox.net/api/queue/acknowledge?id=' . urlencode($task));
    } else {
        echo "當前無任務,等待中...\n";
    }
}

// 持續運行
while (true) {
    $start = microtime(true);
    
    pollQueue();

    $end = microtime(true);
    $elapsed = $end - $start;

    // 如果任務處理花費時間小於 0.5 秒,則 sleep 剩餘時間
    $remaining = 0.5 - $elapsed;
    if ($remaining > 0) {
        $seconds = floor($remaining);
        $nanoseconds = ($remaining - $seconds) * 1e9;
        time_nanosleep($seconds, (int)$nanoseconds);
    }
}

四、注意事項

  1. 異常處理time_nanosleep可能會被信號中斷,建議加上異常或中斷檢測來處理返回值。

  2. 高並發場景:輪詢方式不適合高並發或延遲敏感的任務,建議結合消息隊列如RabbitMQ、Redis Streams 使用。

  3. CPU 佔用控制:定時輪詢可能會造成一定的CPU 佔用,建議加入資源監控機制。

五、結語

雖然PHP 通常不用於高精度的任務調度,但藉助time_nanosleep函數,我們仍然可以構建一個簡潔、有效的任務輪詢機制。以上示例提供了一個基礎框架,可根據具體業務需求進行擴展和優化。在小規模、輕量級任務管理場景中,這種方式足夠高效、靈活。