在實際開發中,輪詢是一種常見的任務調度方式,尤其在處理隊列任務時。 PHP 雖然不是天然適合長駐內存的語言,但在CLI 模式下結合合理的時間控制,也能實現相對精確的輪詢控制。本文將介紹如何使用PHP 的time_nanosleep函數實現每0.5 秒精確輪詢隊列任務。
PHP 提供了多個延遲執行的函數,如sleep 、 usleep和time_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);
}
}
異常處理: time_nanosleep可能會被信號中斷,建議加上異常或中斷檢測來處理返回值。
高並發場景:輪詢方式不適合高並發或延遲敏感的任務,建議結合消息隊列如RabbitMQ、Redis Streams 使用。
CPU 佔用控制:定時輪詢可能會造成一定的CPU 佔用,建議加入資源監控機制。
雖然PHP 通常不用於高精度的任務調度,但藉助time_nanosleep函數,我們仍然可以構建一個簡潔、有效的任務輪詢機制。以上示例提供了一個基礎框架,可根據具體業務需求進行擴展和優化。在小規模、輕量級任務管理場景中,這種方式足夠高效、靈活。