Émission Underscore #161 du 24 novembre 2019

Actu

Les FAILs du mois

Chiptune: Jogeir Liljedahl – Physical Presence Virgill Chiptune RMX

Sujet : Le multi-tâches, comment ça marche ?

Je vais tenter de vulgariser un peu ce qu’on entend par « multi-tâches », sans donner un cours d’informatique…

Rappel : CPU, OS et noyo

Un processeur ne sait qu’exécuter des instructions. Une longue suite d’instructions plus ou moins monotones.

Il y a plusieurs catégories d’instructions : les opérations arithmétiques, les déplacements de données, les sauts (pour aller ailleurs dans le code, souvent suivant une condition, par exemple le résultat de la dernière addition).

Cependant, il existe des mécanismes dans la plupart des processeurs permettant mettre ce qu’on fait de côté temporairement pour faire autre chose, puis de revenir à la tâche initiale.
Le plus courant est l’interruption.

Lorsqu’une interruption arrive, ou plutôt lorsqu’elle est traitée, c’est à dire habituellement entre les instructions, le processeur va sauver un minimum de contexte, au minimum l’adresse de la prochaine instruction à exécuter, et l’adresse de la pile, la partie de la mémoire où on stocke généralement les arguments des fonctions, les variables locales du programme…
On parle aussi d' »exception », en fait souvent l’interruption désigne une sous-catégorie des exceptions, réservée aux exceptions d’origine matériel (par exemple la souris a bougé et donc une donnée est disponible pour son pilote).
D’autres sources d’exceptions peuvent être les erreurs mathématique (on vous a dit de ne pas diviser par zéro au fond de la classe), ou même logicielle, puisque certaines instructions servent justement à déclencher une exception.
L’intérêt c’est que lorsque le processeur traite une exception il a en général plus de privilèges. C’est donc une méthode très utilisée pour appeler le système d’exploitation depuis un simple programme.

Un système d’exploitation, c’est un programme, donc un ensemble d’instructions qui vont permettre à d’autres programmes de s’exécuter facilement, avec une interface uniforme. Souvent les programmes lui délèguent la gestion des fichiers et de plein d’autres choses.

Le noyau est ce qui constitue le chef d’orchestre de l’OS, c’est lui qui va décider de l’ordre dans lequel les entrées sorties vont se faire, ou les programmes s’exécuter.

Une petite subtilité difficile à comprendre ici : même s’il on dit qu’un programme s’exécute, en fait c’est bien le processeur qui exécute les opérations, au nom du programme.

Cela vaut pour les applications tout comme l’OS et son noyau.

Et lorsque l’on dit que l’on « rentre dans le noyau », qu’on « appelle le noyau », en fait on demande au processeur d’exécuter une fonction dans ce même noyau, mais avec les privilèges requis, c’est à dire après s’être assuré qu’on en avait le droit. En général, comme on l’a déjà dit… avec une instruction qui déclenche une exception. Y en a deux qui suivent !

Le mono-tâche

Au tout début, les OS se contentaient de permettre de lancer d’autres programmes, et de leur fournir une interface pour accéder aux fichiers, à l’écran, au clavier. C’est le cas des DOS (Disk Operating System), dont le nom indique bien qu’ils ne servent qu’à ça.

Le DOS chargeait un programme en mémoire, puis lui « passait la main », c’est à dire utilisait une instruction du processeur pour qu’il exécute ce programme. Souvent c’était un simple saut vers la première instruction du programme, puisqu’aucune protection mémoire n’existait.

Donc pour pouvoir faire plusieurs choses en même temps, il fallait ruser.

L’astuce consiste donc à lancer un premier programme, qui va installer un gestionnaire d’interruption (un petit bout de code qui en général ensuite appelle le gestionnaire existant) pour une interruption spécifique, par exemple celle de l’horloge qui donc sera déclenché régulièrement, puis de rendre la main au DOS avant de bien s’être assuré qu’il ne libère par la partie de la mémoire qui contient le gestionnaire.
C’est ce qu’on appelle un TSR (Terminate and Stay Resident).
Une même interruption peut parfois être détournée plusieurs fois en chaînant les gestionnaires.

Ensuite le DOS continue son travail, et on peut lancer un autre programme.

Sauf qu’à chaque fois que l’horloge générera une interruption, le processeur s’arrêtera son travail, et passera à la première instruction du premier gestionnaire, la deuxième… puis la première instruction du second gestionnaire et ainsi de suite, jusqu’à ce qu’une instruction lui dise « ça y est on a fini de gérer l’interruption, tu peux dépiler le contexte et reprendre ton travail normal », et là il exécutera alors ce qui aurait du être l’instruction suivante du programme en cours.

Certains TSR ajoutaient des fonctions au DOS ou affichaient l’heure à l’écran.

Le multi-tâches coopératif

Ensuite des gens se sont dit que ce serait bien si les programmes pouvaient coexister normalement sans devoir bidouiller.

Ils ont donc créer des OS permettant aux applications de leur dire quand elles étaient d’accord pour qu’une autre puisse bosser.

Bien sûr il faut que les applications se comportent correctement et soient architecturées pour.

La méthode classique est d’écrire l’application avec ce qu’on appelle une boucle d’évènements.

Après avoir initialisé ce dont elle a besoin, elle (ou plutôt, vous l’avez compris, le processeur en son nom) va exécuter une suite d’instruction qui vont demander à l’OS si elle a quelque chose à faire, traiter cet évènement, puis reboucler jusqu’à ce qu’il n’y ait plus d’évènement à traiter.

Souvent c’est fait au niveau de l’interface graphique car c’est elle qui a rendu nécessaire la cohabitation d’applications entre elles pour proposer des fenêtres.

C’est ainsi que les premiers Windows (qui étaient encore des interfaces graphiques pour DOS et pas des OS complets) fonctionne. Mais aussi la plupart des OS de l’époque, comme les MacOS, le GEM d’Atari…

La couche (interface graphique ou OS) met donc à disposition un ensemble de fonctions dont certaines vont explicitement autoriser que l’application soit stopée pour qu’une autre reprenne son travail.

Ici encore c’est toujours le processeur qui exécute tout ça.

Si chaque application traite les messages rapidement on peut donner l’illusion que ça marche à peu près ensemble.
À l’époque où le contenu des fenêtres ne changeait pas constamment c’était utilisable encore.

L’avantage : c’est plus simple à coder.

L’inconvénient : si une application en coopère pas, elle blo

que tout le monde.
De plus, certains traitements ne sont pas facilement découpables pour laisser aux autres applications un peu de temps.

Le multi-tâches préemptif

Certains ont vu les choses autrement.

Ils se sont dit qu’il valait mieux que les applications croient qu’elles tournent tout le temps.

Dans ce cas, on utilise le mécanisme des exceptions pour régulièrement (ou pas d’ailleurs, ça s’appelle le tickless, Linux l’a inventé mais BeOS le faisait y a 20 ans) interrompre l’application en cours.
Le noyau va donc sauver le contexte entier de l’application : la valeurs des registres non privilégiés, l’adresse actuelle de la pile… et bien plus quand on supporte la protection mémoire.
L’ordonnanceur choisit ensuite quelle application reprend.
Le contexte de cette appli est alors restauré puis on (enfin, toujours le processeur) exécute une instruction qui sort de l’exception.
Sauf qu’à l’entrée on était dans une application, et au retour on est dans l’autre.

Si on fait ça très vite, chaque appli fonctionne comme si elle avait un processeur entier pour elle, jute plus lent.
Chaque application avec son contexte est appelée un processus.

On dit que le noyau préempte les applications.

Maintenant les noyaux eux-même sont souvent prémptifs, c’est à dire qu’il s’autorisent à faire plusieurs choses en même temps. Ça complexifie le code, mais ça permet plus de fluidité.

Le multithreading

Parfois une application elle-même veut faire plusieurs chose ne même temps.

Elle va alors créer des threads, des fils d’exécutions qui sont en fait comme des applications, mais qui partagent le même contexte (à l’exception des registres et de la pile).

Le SMP

Jusqu’ici je n’ai parlé du processeur qu’au singulier. Pendant longtemps on utilisait qu’un seul processeur, qui n’avait qu’un seul cœur.

Mais on a voulu utiliser plusieurs processeurs.

SMP veut dire Symetric Multi-Processing.

Là on peut faire pareil sauf qu’il faut que chaque processeur s’assure qu’il n’exécute pas certaines instructions en même temps, sinon c’est la catastrophe.

On a recours à tout un tas de trucs pour les synchroniser entre eux.

Mais c’est une autre histoire.

Chiptune: Virgill – Angry Nerds

Agenda

Rappelons que l’agenda est celui de la semaine passée lors des rediffusions le samedi.

RGC : Retro Gaming Connexion

le 30 novembre et 1er décembre 2019 au Colissée de Meaux, la nouvelle salle des fêtes de Meaux (77100) du samedi 10h au dimanche 18h

Premier Contribatelier Grenoblois

Fini la consommation, passons à la contribution ! Que vous soyez familier du code ou novice du numérique, cet atelier vous propose de découvrir comment contribuer aux logiciels et à la culture libre, dans la convivialité d’un apéro partagé.
Atelier organisé par Framasoft.

Sur inscription (sur le framaforms) ;
Le lundi 2 décembre, de 18h30 à 21h ;
La Turbine.Coop, 5 esplanade Andry Farcy, Grenoble, 38000 France.

Astrologeek

  • sysadmin : Il s’est fait lapider : Connection reset by pierre.
  • technophile : J’ai une couette USB… Quel que soit le sens où je la mets dans housse c’est le mauvais
  • hacker : Quand Chuck Norris se logue sous Linux, son UID est -1.
  • codeur : Qui prend le do sur odoo ?
  • microsofteux : C’est Casper, le gentil fantôme ! – Oué enfin, gentil sauf aux sports d’hiver ! Parce que Casper skie…
  • procrastinateur : Marguerite duRàZ, elle est resté coincée sur la page blanche ?