Comment le programmateur du système d’exploitation reprend-il le contrôle du processeur?

J’ai récemment commencé à apprendre comment fonctionne le processeur et le système d’exploitation, et je suis un peu perplexe quant au fonctionnement d’une machine à un seul processeur avec un système d’exploitation multitâche.

En tant que tel, en supposant que ma machine ait un seul processeur, cela signifierait qu’à tout moment, un seul processus pourrait être exécuté.

Maintenant, je ne peux que supposer que le planificateur utilisé par le système d’exploitation pour contrôler l’access au précieux temps CPU est également un processus.

Ainsi, sur cette machine, le processus utilisateur ou le processus du système de planification s’exécutent à un moment donné, mais pas les deux.

Alors, voici une question:

Une fois que le programmateur cède le contrôle du processeur à un autre processus, comment peut-il récupérer le temps CPU pour s’exécuter à nouveau pour effectuer son travail de planification? Je veux dire, si un processus en cours d’exécution ne renonce pas (céder) au processeur, comment le planificateur lui-même pourrait-il fonctionner à nouveau et garantir un traitement multitâche correct?

Jusqu’à présent, je pensais que si le processus utilisateur demandait une opération d’E / S via un appel système, alors dans l’appel système, nous pourrions nous assurer que le planificateur se voit à nouveau allouer du temps CPU. Mais je ne suis même pas sûr que cela fonctionne de cette manière.

D’un autre côté, si le processus utilisateur en question était insortingnsèquement lié au processeur, alors, de ce sharepoint vue, il pourrait s’exécuter indéfiniment, ne laissant jamais exécuter d’autres processus, pas même le planificateur.

En supposant une planification par tranches de temps, je n’ai aucune idée de la manière dont le planificateur pourrait réduire le temps d’exécution d’un autre processus, alors qu’il n’est même pas en cours d’exécution.

J’apprécierais vraiment n’importe quel aperçu ou références que vous pouvez fournir à cet égard.

Le système d’exploitation configure une timer matérielle (timer à intervalle programmable ou PIT) qui génère une interruption tous les N millisecondes. Cette interruption est transmise au kernel et le code utilisateur est interrompu.

Cela fonctionne comme n’importe quelle autre interruption matérielle. Par exemple, votre disque forcera un basculement vers le kernel lorsqu’il aura terminé une IO.

Google interrompt. Les interruptions sont au centre des kernelx multithreading, préemptifs comme Linux / Windows. Sans interruptions, le système d’exploitation ne fera jamais rien.

En étudiant / apprenant, essayez d’ignorer les explications qui mentionnent «interruption de timer», «round-robin» et «time-slice», «quantum» dans le premier paragraphe – elles sont dangereusement trompeuses, voire erronées.

Les interruptions, en termes de système d’exploitation, se présentent sous deux formes:

Interruptions matérielles – celles déclenchées par un signal matériel réel provenant d’un périphérique. Celles-ci peuvent se produire à (presque) n’importe quel moment et basculer l’exécution de n’importe quel thread en cours d’exécution pour coder dans un pilote.

Les interruptions logicielles – celles initiées par les appels du système d’exploitation provenant des threads en cours d’exécution.

Chacune des interruptions peut demander au planificateur de faire en sorte que les threads en attente soient prêts ou en cours d’exécution ou que les threads en attente / en cours d’exécution soient préemptés.

LES INTERRUPTIONS LES PLUS IMPORTANTES SONT CES INTERRUPTIONS MATERIELLES DES PILOTES PERIPHERIQUES, – celles qui préparent les threads qui attendent sur IO des disques, des cartes NIC, des souris, des claviers, des clés USB, etc. Le locking, la synchronisation, la signalisation, etc., ont de très bonnes performances, car les périphériques matériels peuvent rapidement préparer les fils à attendre des données de ce matériel, sans aucune conséquence des fils qui ne se déplacent pas ou en attente RESCHEDULE DE MINUTERIE.

L’interruption de la timer matérielle qui provoque des planifications périodiques est importante car de nombreux appels système ont des délais d’attente au cas où, par exemple, une réponse d’un périphérique prend plus de temps que prévu.

Sur les systèmes multicœurs, le système d’exploitation dispose d’un pilote interprocesseur qui peut provoquer une interruption matérielle sur d’autres cœurs, permettant ainsi au système d’exploitation d’interrompre / de planifier / d’envoyer des threads sur plusieurs cœurs.

Sur les boîtiers gravement surchargés, ou ceux exécutant des applications gourmandes en ressources processeur (une petite minorité), le système d’exploitation peut utiliser les interruptions périodiques du minuteur, et donc la planification en résultant, pour parcourir un ensemble de threads supérieurs au nombre de cœurs disponibles. et ainsi permettre à chacun une part des ressources CPU disponibles. Sur la plupart des systèmes, cela se produit rarement et a peu d’importance.

Je suis désolé pour les cris, mais chaque fois que je vois «quantum», «abandonne le rest de leur temps», «round-robin» et similaire, je me suis juste effondré.

Pour compléter la réponse de @ usr, en citant la section Comprendre le kernel Linux :

La fonction schedule ()

schedule () implémente le planificateur. Son objective est de trouver un processus dans la liste des files d’attente puis d’y affecter le processeur. Il est appelé, directement ou paresseusement, par plusieurs routines du kernel. […]

Invocation paresseuse

Le planificateur peut également être appelé paresseusement en définissant le champ need_resched du [processus] actuel sur 1. Comme une vérification de la valeur de ce champ est toujours effectuée avant de reprendre l’exécution d’un processus en mode utilisateur (voir la section «Retour from Interrupts and Exceptions »dans le chapitre 4), schedule () sera certainement invoqué à une date ultérieure proche.