Question

Si vous consultez la clock_gettime () fonction, qui est disponible dans tous les BSD et est en fait définie comme faisant partie du standard POSIX, vous constatez la prise en charge d'au moins trois types d'horloge (de nombreux systèmes prennent en charge davantage que ces horloges, mais en réalité le standard POSIX ne demande qu'une seule fonction. être présent, tous les autres sont facultatifs):

  • CLOCK_REALTIME - POSIX demande que cette information soit présente. Ceci est l'horloge murale.

  • CLOCK_MONOTONIC - Aucune idée de ce que cela signifie (et de la signification des secondes SI), mais je comprends que cette horloge ne reculera jamais, elle ne peut que gagner de la valeur de façon monotone.

  • CLOCK_UPTIME - je ne vois pas en quoi cela diffère de CLOCK_MONOTONIC (le temps de disponibilité ne revient jamais non plus en arrière), mais au moins, je sais que cette horloge commence à zéro lorsque le noyau démarre sa valeur initiale, CLOCK_MONOTONIC, ne sera pas définie au démarrage du noyau)

Ignorons les autres horloges pendant une seconde. CLOCK_REALTIME n'est pas garanti de compter de manière monotone vers le haut, non? Il s'agit de la "durée du système" réelle. Je peux modifier l'heure du système à volonté. Je peux le configurer 3 mois ou 5 ans plus tard et chaque fois que mon système synchronise l'heure à l'aide d'un serveur NTP sur le réseau, l'heure peut avancer ou reculer.

Nous avons maintenant deux fonctions de sommeil dans un système BSD. sommeil () et nanosleep () . Je ne suis pas sûr, mais je m'attendrais à ce que sleep () soit implémenté au-dessus de nanosleep, après tout, je peux facilement émuler sleep () en utilisant nanosleep () et définir uniquement le nombre de secondes dans la structure, en maintenant nanoseconds à zéro. .

J'ai lu dans de nombreuses sources que ces fonctions fonctionnent en calculant l'heure de réveil (obtenir l'heure actuelle, y ajouter une durée de veille) et que le système vérifie ensuite à intervalles réguliers si l'heure actuelle est . plus tard que l'heure de réveil et si c'est le cas, le fil sera réactivé. C’est parce que cela n’est vérifié que par intervalles que les pages de manuel disent que le sommeil en cours dormira au moins pendant cette durée (plus court seulement si un signal l’interrompt), mais il risque de dormir plus longtemps (selon la fréquence le système vérifie si nous avons déjà dépassé l'heure de réveil et en fonction du temps requis par le planificateur pour permettre à ce fil de s'exécuter à nouveau).

Tout cela est parfaitement sain pour moi ... mais il y a une question qui m'a toujours dérangé:

Selon diverses sources, les personnes qui dorment (au moins le nanosleep) utilisent CLOCK_REALTIME comme horloge en interne. Cela signifie que, si vous dites à nanosleep () de dormir pendant 30 secondes, puis modifiez mon horloge système à 1 heure dans l’avenir, le fil de discussion se réveillera presque immédiatement (une heure dans l’avenir est bien en avance sur le temps de réveil nanosleep ( ) calculé). C'est aussi parfaitement d'accord. Toutefois , que se passe-t-il si je dis réveiller dans 30 secondes, puis que l'utilisateur découvre que son horloge système a une heure d'avance et le retarde d'une heure? Ensuite, mon fil va dormir pendant 1 heure et 30 secondes? Comme ce serait plutôt mauvais.

Était-ce utile?

La solution

Pour autant que je sache, les fonctions de veille sont généralement mises en œuvre comme un compteur de décrémentation. Vous dites "dormir pendant 10 secondes". qui se traduit par un "sommeil de 1 000 ticks de calendrier" dans le planificateur, puis chaque fois qu'il vérifie les processus en veille, il décrémente la durée restante.

De cette façon, le temps de sommeil sera toujours une quantité de temps réel pour dormir, au lieu de dormir jusqu’à un moment dans l’avenir. La raison en est que vous vous en doutez, si nous choisissons une heure dans le futur, nous pourrions ne jamais y arriver (ou y arriver dans un laps de temps inattendu). Cela correspond à l'utilisation que vous souhaitez faire du sommeil dans un programme. Ce n'est pas fait pour faire des calculs comme un calendrier.

Vous pouvez également effectuer un test simple, mettre un programme en veille pendant 30 secondes, utiliser le nix " time " commande pour chronométrer la durée d'exécution de la fonction et, une fois celle-ci démarrée, modifiez votre horloge système de 5 minutes en arrière et voyez ce qui se passe.

Autres conseils

Le thread va vérifier sur un compteur interne qui est défini sur la durée du sommeil et non sur le point final du sommeil. Le compteur interne utilisé n'a rien à voir avec l'heure système actuelle et ne sera donc pas affecté si des modifications sont apportées à l'heure système.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top