Skip to main content

Concurrence et synchronisation

Les systèmes d'exploitations actuels induisent inévitablement de la concurrence car plusieurs files d'exécution sont simultanées (machines multi-processeur / coeur ...). De plus l'existence d'instructions non-atomiques ainsi que de la préemption font que nous n'avons aucune garantie que quelqu'un d'autre n'est pas en train de modifier la même ressource que nous.

Deux types de concurrence sont observables, la concurrence physique de différentes tâches (possible uniquement avec une machine multiprocesseur) provoquée par un vrai accès concurrent au matériel. Et la concurrence logique pouvant être provoquée par un accès interrompu par la préemption ou par une interruption matérielle.

Une différence notable concernant la gestion de la concurrence entre le noyau et l'espace utilisateur est la capacité du noyau à maîtriser la préemption et les interruptions. En effet il peut empêcher la concurrence logique en empêchant les autres acteurs ou événements de s'exécuter. Quant à lui l'espace utilisateur n'a aucune maîtres.

Pour contrer cela nous allons utiliser des verrous. Rappelons qu'il existe deux types de verrous : ceux à attente active qui vont consommer beaucoup de CPU mais vont être très réactifs. Et ceux à attente passive qui vont se mettre en sommeil jusqu'à ce qu'il soit réveillé par une autre tâche via l'ordonnanceur. Cela est peu réactif mais consomme peu de CPU. Ces mécanismes vont permettre de mettre en place des protections contre la famine ou les deadlocks (dépend de l'implémentation). En revanche en espace utilisateur, l'ordonnanceur noyau n'a pas connaissance des verrous pris. La préemption peut rendre une section critique très longue et peut passer la main à une tâche qui va essayer de prendre le même verrou. En somme, en espace utilisateur l'attente passive est préférable.

Sur Linux le coût de synchronisation est critique, il existe beaucoup de variante dans Linux notamment les variantes à attente active. De plus la préemption est désactivée quand un verrou à attente active est pris. (Garantie d'avoir une section critique courte). Pour éviter de faire exploser le coût en utilisant uniquement des verrous, il est bon d'utiliser des instructions atomiques permettant d'éviter la concurrence.

Concernant les interruptions, le processeur peut être interrompu n'importe quand (périphériques, horloge) y compris au milieu d'une section critique ! Il est donc nécessaire de désactiver les interruptions lors des sections critiques. Cela est faisable grâce à des instructions dédiées pour désactiver les interruptions vers ce processeur mais il ne faut pas les désactiver trop longtemps (nuit à la réactivité).