web-dev-qa-db-fra.com

Comment dormant un fil de fil?

Lorsque vous Dormez Un fil, qu'est-ce qui se passe réellement?

Je vois que dormir un fil "pause le fil actuel pendant une période donnée". Mais à quoi ça marche?

Selon - comment thread.sleep () fonctionne en interne et Comment threadsep fonctionne-t-il vraiment? :

  • la durée du sommeil sera soumise à une granularité spécifique au système
  • dormir est Blocage
  • le fil quitte la CPU et arrête son exécution
  • le fil ne consommait pas de temps de CPU tout en dormant

Je ne peux tout simplement pas comprendre la mécanique interne et fondamentale de ce que tout cela signifie.

Je comprends qu'il y a quelque chose appelé le planificateur responsable de la commutation entre les threads.

Les sources semblent indiquer que cela varie selon le système d'exploitation (ou le matériel?) Et la plupart des filets sont donnés 1 ms - 60 ms ou de manière à effectuer certaines actions avant que la CPU ne passe sur un autre fil.

Mais quand un fil dort (par exemple, plusieurs secondes), comment cela reprend-il? Je suppose qu'une minuterie est impliquée d'une manière ou d'une autre, est-ce l'horloge de la carte mère? Est-ce lié au taux d'horloge de la CPU?

Et même si une minuterie est impliquée, comment le CPU savait-il quand il est temps de faire attention au fil à nouveau? Ne serait-il pas obligé d'enregistrer constamment sur le fil pour voir si c'est prêt? N'est-ce pas efficacement sondage et donc type de est consommer du temps de processeur?

Domaine est-il spécifique à la langue du fil ou est-il responsable de celui-ci ou est-ce une chose spécifique à la CPU?

Quelqu'un voudrait-il m'expliquer cela avec des explications fondamentales de choses comme le planificateur et de ce que fait la CPU pendant tout cela?

13
Rowan Freeman

Comme Doc Brown mentionné dans un commentaire, les interruptions sont la clé et non seulement pour dormir.

Une interruption est un signal matériel que le processeur doit arrêter ce qu'il fait et exécuter un morceau de code. Les périphériques externes déclenchent des interruptions lorsqu'ils ont besoin de l'attention du processeur: par exemple, lorsqu'un disque a fini de lire des données ou une touche est appuyée sur une touche ou un compte à rebours sur la carte mère a atteint zéro.

Le code d'interruption-manipulation est généralement très petit et très rapide. Par exemple, lorsque le disque indique qu'un bloc a été copié à la mémoire, le système d'exploitation peut simplement enregistrer ce fait dans une liste de "blocs prêts" quelque part, puis de retourner à l'autre que ce soit. Vous ne voulez pas que la CPU passe tout son temps dans l'interruption du code de manutention et ne pas exécuter de code d'utilisateur.

Un code de code entraîné par une interruption qui n'est pas nécessairement petit est le planificateur. Il est déclenché par un signal d'un compte à rebours et examine l'état du système chaque fois qu'il est exécuté. Cela inclura généralement généralement des processus d'identification prêts à être exécutés (par exemple, car le bloc qu'ils attendaient est arrivé en mémoire), ainsi que ceux qui ont épuisé leur tranche de temps.

Donc, lorsque vous exécutez un sommeil à fil, ce que vous faites, c'est dire à l'OS qui (1) vous abandonnez votre tranche de temps, et (2), vous ne devriez pas être réveillé à nouveau avant que un certain temps ne soit écoulé.

Chaque fois que le planificateur est exécuté, il examinera votre fil et ne le marquez que comme "prêt à exécuter" si ce temps s'est écoulé. C'est un sondage, d'une sorte, mais ce n'est pas une "boucle occupée" puisqu'il est déclenché par une interruption. Ce n'est pas non plus si cher: il n'y a généralement que mille threads à la fois.

Cela devrait également vous donner une idée pourquoi les temps de sommeil ne sont pas exacts: lorsque votre fil devient prêt à courir, il peut y avoir d'autres threads toujours en cours d'exécution et n'ont pas épuisé leur tranche de temps. Ou il peut y avoir des threads plus prioritaires prioritaires prêts à courir.

6
kdgregory