Chapitre 3
Programmation multitâche temps réel en langage C avec la norme
POSIX
10/10/24 NASRI Hani 1
Une application multitâche est un programme informatique constitué de plusieurs tâches s'exécutant de
manière concurrente. Elle est dite temps réel lorsque son bon fonctionnement ne dépend pas seulement de
son exactitude, mais aussi du respect des contraintes temporelles affectées aux tâches. Ainsi, lors de la
conception d'une application multitâche temps réel, de nombreuses problématiques liées à la gestion de
l'exécution concurrente entre les tâches sont à prendre en compte dans leur programmation : la création
effective des tâches, la périodicité de certaines tâches, l'affectation des priorités et du type
d'ordonnancement des tâches, la gestion de la synchronisation entre tâches, la gestion du problème
d'inversion de priorité et la gestion de la communication entre tâches. Dans ce cours, nous nous proposons
de présenter comment chacune de ces problématiques peut être traitée dans un programme écrit
en langage C à l'aide de la bibliothèque pthread définie dans la norme POSIX.
10/10/24 NASRI Hani 2
Qu'est-ce que POSIX (Portable Operating System Interface) ?
POSIX (Portable Operating System Interface) est un ensemble d'interfaces de système d'exploitation
standard basées sur le système d'exploitation UNIX . Les spécifications POSIX les plus récentes,
IEEE Std 1003.1-2017, définissent une interface et un environnement standard qui peuvent être
utilisés par un système d'exploitation ( OS) pour fournir un accès aux applications compatibles
POSIX. La norme définit également un interpréteur de commandes ( Shell) et des programmes
utilitaires courants . POSIX prend en charge la portabilité des applications au niveau du code source
afin que les applications puissent être créées pour s'exécuter sur n'importe quel système d'exploitation
compatible POSIX.
10/10/24 NASRI Hani 3
Dans ce cours, nous considérons que l'application multitâche est exécutée sur
une plate-forme monoprocesseur (un seul processeur). L'exécution parallèle
des tâches est alors virtuelle dans ce cas. Ainsi c'est donc au système
d'exploitation installé sur l'architecture matérielle sur laquelle s'exécute
l'application d'utiliser ses mécanismes internes pour gérer l'exécution des
différentes tâches de l'application, afin de leurs permettre de respecter leurs
différentes contraintes.
10/10/24 NASRI Hani 4
Installation et utilisation de Pthread
Il est possible d'écrire des programmes multitâches avec pthread aussi bien sur
Windows que sur Linux. Linux par défaut dispose déjà d'une
bibliothèque pthread qui lui est intégrée, tandis que Windows n'en dispose pas.
Il est donc nécessaire de l'installer sur ce dernier. Par la suite, nous
présenterons les différentes étapes d'installation de pthread sous Windows. Puis
nous présenterons également les différents éléments nécessaires pour
l'exécution d'un programme utilisant pthread sur Linux.
10/10/24 NASRI Hani 5
Sous windows : La bibliothèque pthread est téléchargeable ici. Pour l'instant, toutes les fonctions définies dans cette bibliothèque ne sont
pas encore implémentées, ce qui limite sa portabilité. L'ensemble des éléments implémentés et non implémentés de pthread sont visibles
à travers le lien suivant. Sur la page de pthread, téléchargez le fichier exécutable le plus récent, actuellement : pthreads-w32-2-8-0-
release.exe. Exécutez-le pour dézipper son contenu dans un répertoire de votre choix. Si vous utilisez par exemple Code::Blocks
(exemple de la version 12.11), voici la procédure à suivre :
Ø répérez l'emplacement du compilateur C (MinGW) dans le répertoire d'installation de Code::Blocks sous votre machine (ex:
C:\Program Files\CodeBlocks\MinGW)
Ø copiez les fichiers .h situés dans le répertoire ..\Pre-built.2\include du dossier où vous avez dézippé la librairie pthread téléchargée
précédemment. Collez ces fichiers dans le répertoire C:\Program Files\CodeBlocks\MinGW\include ;
Ø copiez les fichiers .a et .lib situés dans le répertoire ..\Pre-built.2\lib du dossier où vous avez dézippé la librairie pthread. Collez ces
fichiers dans le répertoire C:\Program Files\CodeBlocks\MinGW\lib
Ø copiez les fichiers .dll situés dans le répertoire ..\Pre-built.2\lib du dossier où vous avez dézippé la librairie pthread. Collez ces fichiers
dans le répertoire C:\Program Files\CodeBlocks\MinGW\bin.
10/10/24 NASRI Hani 6
Sous le système d'exploitation Linux, le compilateur C qui y est intégré dispose
d'ores et déjà de la bibliothèque pthread. Il ne nécessite donc aucune
installation. Pour écrire votre programme, créez un fichier d'extension .c, avec
l'éditeur de texte gedit par exemple (pour de petits programmes, sinon vous
pouvez installer un IDE dédié). Lors de la compilation et de l'exécution de votre
programme (nommé par exemple monprogramme.c), sous la console, placez-
vous dans le répertoire où il se trouve et exécutez respectivement les
commandes suivantes :
Øgcc -lpthread -o monprogramme monprogramme.c (pour la compilation) ;
Ø./monprogramme (pour l'exécution).
10/10/24 NASRI Hani 7
Création de tâches sous Posix
10/10/24 NASRI Hani 8
Attendre la fin d'une tâche
10/10/24 NASRI Hani 9
Petit programme à 2 tâches
10/10/24 NASRI Hani 10
Code Source
10/10/24 NASRI Hani 11
Nous remarquons lors de l'exécution un ordre d'affichage arbitraire entre les tâches
1 et 2. Cet ordre d'affichage peut varier d'une exécution à une autre
10/10/24 NASRI Hani 12
Forcer la non-attente d'une tâche
10/10/24 NASRI Hani 13
Priorité et ordonnancement de
tâches
10/10/24 NASRI Hani 14
Priorité et ordonnancement de
tâches
10/10/24 NASRI Hani 15
Priorité et ordonnancement de
tâches
10/10/24 NASRI Hani 16
Priorité et ordonnancement de
tâches
10/10/24 NASRI Hani 17
Le code
Source
10/10/24 NASRI Hani 18
Priorité et ordonnancement de
tâches
10/10/24 NASRI Hani 19
Gérer le partage de données entre tâches
10/10/24 NASRI Hani 20
Gérer le partage de données entre tâches
L'une d'entre elles (la tâche 2) peut par exemple écrire sur la donnée partagée pendant que l'autre (la tâche 1) est chargée de
la lire. Pour gérer le problème de la cohérence de la donnée partagée (c'est-à-dire éviter qu'elle soit corrompue au travers des
accès aléatoires), il faut éviter par exemple qu'une tâche lise la donnée pendant qu'elle est entrain d'être modifiée, ou qu'une
tâche modifie la donnée pendant qu'elle est entrain d'être lue. Pour résoudre ce problème, des mécanismes d'exclusion
mutuelle doivent dont être mis sur pied pour protéger la donnée partagée. Nous allons montrer comment cela peut être fait
sous Posix.
10/10/24 NASRI Hani 21
Exclusion mutuelle
10/10/24 NASRI Hani 22
Source Code
10/10/24 NASRI Hani 23
Resultat
10/10/24 NASRI Hani 24
Exclusion mutuelle et variable c
10/10/24 NASRI Hani 25
Exclusion mutuelle et variable c
10/10/24 NASRI Hani 26
Le code ci-dessous reprend
l'exemple du paragraphe V-
A précédent, en intégrant
une variable condition. La
tâche 1 ne peut lire qu'un
poids et une taille
supérieurs respectivement
à 60kg et 120cm, sinon, elle
s'endort.
10/10/24 NASRI Hani 27
Resultat
10/10/24 NASRI Hani 28