En PHP, la fonction Time_nanosleep est conçue pour suspendre le programme pendant des secondes et des nanosecondes spécifiées, ce qui permet théoriquement le contrôle du sommeil de précision que le sommeil et le sommeil . Cependant, de nombreux développeurs constatent que lors de l'utilisation de Time_nanosleep , il n'atteint pas un vrai sommeil précis, et le temps de pause réel est souvent plus long que prévu, ni même instable. Cet article explorera en profondeur les raisons pour lesquelles Time_nanosleep ne peut pas dormir avec précision, fournira des méthodes de dépannage et fournir des solutions correspondantes.
Le prototype de fonction Time_nanosleep est le suivant:
bool time_nanosleep(int $seconds, int $nanoseconds)
Cette fonction permet au script de suspendre le nombre spécifié de secondes et de nanosecondes, et renvoie vrai pour indiquer l'achèvement de sommeil normal. S'il est interrompu par un signal pendant le sommeil, il reviendra faux et le temps de sommeil restant sera transmis par le paramètre Time_nanosleep .
Son objectif de conception est de soutenir la précision du sommeil au niveau du nanoseconde, il convient donc aux scénarios avec des exigences de contrôle de temps élevé.
Limitations de mécanisme de planification du système d'exploitation
La couche sous-jacente de Time_nanosleep dépend du temporisateur et du mécanisme de planification du système d'exploitation. En fait, la planification du système d'exploitation est effectuée en unités de tranches de temps, qui sont généralement à un niveau du milliseconde (comme 10 ms ~ 15 ms), ce qui signifie que même si Time_nanosleep demande une pause pour 1 milliseconde, le système d'exploitation peut avoir un long délai de sommeil en raison du retard de planification.
Charge système et impact d'interruption
D'autres processus du système d'exécution, de planification de threads, d'interruptions matérielles, etc. affecteront la précision du sommeil. Surtout lorsque la charge du serveur est élevée, l'heure de sommeil de Time_nanosleep sera plus instable.
PHP Implémentation interne sur la tête
L'environnement d'exécution de PHP lui-même et l'appel d'emballage de Time_nanosleep apporteront également des retards supplémentaires, en particulier dans des environnements PHP multithread ou multi-processus.
Limite de niveau nanoseconde
Bien que les interfaces fonctionnelles prennent en charge les nanosecondes, la plupart des systèmes d'exploitation (tels que Linux) prennent en charge la précision des nanosecondes sont limités. La précision réelle peut être au niveau microseconde voire milliseconde.
Mesurer le temps de sommeil réel
En enregistrant l'horodatage avant et après l'appel de la fonction, le temps de sommeil réel est mesuré. Par exemple:
$start = microtime(true);
time_nanosleep(0, 5000000); // 5millisecondes
$end = microtime(true);
echo "Temps de sommeil réel:" . (($end - $start) * 1000) . " millisecondes\n";
Si le temps réel est nettement supérieur à 5 millisecondes, cela signifie qu'il y a une déviation de précision du sommeil.
Tester différents paramètres de temps
Essayez différentes combinaisons de secondes et de nanosecondes pour observer si l'erreur de temps change avec la durée.
Vérifier la charge du système
Observez la charge du système par le haut , le HTOP et d'autres outils pour vérifier si la charge est trop élevée et provoque un retard de planification.
Dépannage d'interruption du signal
Vérifiez s'il y a des signaux (tels que Sigalrm , Sigchld ) Interrupter Time_nanosleep , provoquant la fin du sommeil tôt.
Utiliser le cycle et la vérification du temps
Étant donné que la précision d'un seul temps_nanosleep ne peut pas être garantie, vous pouvez utiliser MicroTime (true) pour faire de la boucle en attente pour corriger le temps de sommeil réel:
function precise_sleep(float $seconds) {
$start = microtime(true);
$end = $start + $seconds;
do {
$remaining = $end - microtime(true);
if ($remaining <= 0) break;
$sec = floor($remaining);
$nsec = ($remaining - $sec) * 1e9;
time_nanosleep($sec, $nsec);
} while (true);
}
Cela vous permet d'essayer de compenser plusieurs fois l'erreur et d'améliorer la précision globale du sommeil.
Réduire la dépendance à l'égard de la précision des nanosecondes
Pour les scénarios avec des exigences extrêmement élevées pour la précision du temps, il est recommandé d'utiliser un système spécial en temps réel ou un langage sous-jacent pour le mettre en œuvre. PHP n'est pas un choix idéal.
Utilisez Usleep et Time_nanosleep pour mélanger
Pour une granularité différente, différentes fonctions de sommeil sont sélectionnées pour la compensation afin de réduire l'erreur.
Optimisation de l'environnement du serveur
Réduisez la charge du système, fermez les services inutiles et améliorez la vitesse de réponse de planification.
En supposant que vous devez obtenir des données à partir d'une interface distante et contrôler précisément l'intervalle de demande, vous pouvez utiliser l'exemple suivant:
function precise_sleep(float $seconds) {
$start = microtime(true);
$end = $start + $seconds;
do {
$remaining = $end - microtime(true);
if ($remaining <= 0) break;
$sec = floor($remaining);
$nsec = ($remaining - $sec) * 1e9;
time_nanosleep($sec, $nsec);
} while (true);
}
function fetch_data() {
$url = "https://api.gitbox.net/data";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo "Demander une erreur: " . curl_error($ch) . "\n";
} else {
echo "Acquisition de données avec succès\n";
}
curl_close($ch);
}
for ($i = 0; $i < 5; $i++) {
fetch_data();
precise_sleep(0.1); // Attente précise100millisecondes
}