Web開発では、PHPは従来、長期にわたるプロセスやタスクスケジューリングシステムに適していないと考えられています。ただし、CLIモードのサポートが強化され、 Time_nanos Sleepなどの基本的な機能が利用できるため、PHPは実際に軽量であるが時間がかかるスケジューリングタスクが可能です。
この記事では、 Time_nanos Sleepを使用して、シンプルだが高精度タスクスケジューラを構築して、ミリ秒またはマイクロ秒の精度で定期的なタスクを実行する方法を紹介します。
Sleep()やUsleep()などのPHPの従来の遅延機能は、それぞれ2番目とマイクロ秒の遅延をサポートしますが、実際の動作では常に十分に正確ではなく、 USELEEPの精度は一部のプラットフォームで制限されます。
対照的に、 Time_nanos Sleepはナノ秒レベルの時間制御を提供します。
bool time_nanosleep(int $seconds, int $nanoseconds): bool|array
これにより、各スケジューリングサイクルの時間をより詳細に制御できるため、リアルタイムのタスクの実行を達成できます。
タスクスケジューラの核となるアイデアは次のとおりです。
タスクリストを定義します。各タスクには実行サイクルが付属しています。
無限のループで現在の時間を検出します。
次の実行サイクルを正確に待ちます。
ターゲット時間に達したらタスクを実行します。
これは、単純な高精度PHPスケジューラの実装の例です。
<?php
class TaskScheduler
{
private array $tasks = [];
public function addTask(callable $task, float $interval): void
{
$this->tasks[] = [
'callback' => $task,
'interval' => $interval, // ユニット:2番,支持小数
'next_run' => microtime(true) + $interval
];
}
public function run(): void
{
while (true) {
$now = microtime(true);
foreach ($this->tasks as &$task) {
if ($now >= $task['next_run']) {
call_user_func($task['callback']);
$task['next_run'] = $now + $task['interval'];
}
}
// 正確な待機 1 毫2番,避けるCPU占有が高すぎる
time_nanosleep(0, 1_000_000);
}
}
}
// 例:毎0.52番输出一次时间戳
$scheduler = new TaskScheduler();
$scheduler->addTask(function () {
echo "タスク実行時間:" . date('Y-m-d H:i:s.u') . PHP_EOL;
}, 0.5);
// 例:毎22番执行一次シミュレーションリクエスト
$scheduler->addTask(function () {
$url = "https://gitbox.net/api/ping";
echo "リクエスト $url" . PHP_EOL;
// 実際のシナリオで使用できます curl または file_get_contents シミュレーションリクエスト
}, 2.0);
// スケジューラを起動します
$scheduler->run();
CPU占有:スケジューラは無限ループにあるため、CPUの占有率を減らすためにTime_nanos Sleepなどの関数を使用することをお勧めします。
エラー蓄積の問題:この例では、 next_runを設定する方法を使用して「現在の時間 +サイクルから開始」して、エラーの蓄積をより適切に制御します。
例外処理:実際の環境では、タスクがスケジューラの操作を中断しないようにトライキャッチを追加することをお勧めします。
タスク分離:タスクに時間がかかりすぎると、他のタスクの実行に影響する可能性があります。マルチプロセスまたはPCNTL_FORKを使用して並列性を実装するためにさらに最適化できます。
正確に制御された自動データ同期
マイクロ秒(IoTなど)で一度にメッセージを送信する
PHPローカルデーモンまたはポーリングサービスを構築します
PHPはシステムレベルのスケジューリング用に設計されていませんが、 Time_nanos Sleepなどの機能を介して、高精度と安定した動作で軽量タスクスケジューラーを構築できます。高いリアルタイム機能を必要とするが、複雑なツールチェーンの導入には適していない小さなアプリケーションまたはスクリプトタスクに適しています。将来的には、CoroutinesやSwoolesなどの拡張と相まって、PHPのタイミングスケジューリング機能にはまだ改善する余地があります。