- 1 - L'environnement de développement
- 2 - Premier programme
- 3 - Les variables
- 4 - Les structures de contrôle
- 5 - Les attributs, les énumerations
- 6 - Les tableaux
- 7 - Les sous-programmes
- 8 - Les types
- 9 - Les packages
- 10 - Le multi-tache
- 11 - Ecrire un programme pour le robot
- 12 - Utilisation de la lib PNG_Interface
- 13 - Exercice : SimpleForth
- 14 - Exercice : Startup_Manager
- 15 - Exercice : Gestion des déplacements
Lancer plusieurs threadsEn Ada, il est très facile de lancer plusieurs tâches simultanément : il faut déjà déclarer la tâche : task body Ma_Tache is ... begin ... end Ma_Tache; et c'est tout, rien de plus facile. Attendre un peuSouvent, une tâche consiste à faire quelque chose, attendre un peu, refaire le quelque chose, attendre un peu, etc, etc... Pour attendre un peu, on pourrait faire une grosse boucle qui ne fait rien, mais le processeur serait très utilisé et donc les autres tâches rameraient. Pour nous aider, Ada propose un package "Ada.Real_Time" qui contient une méthode "Clock" qui renvoie l'heure qu'il est. A cette heure, on peut ajouter des "Time_Span" qu'on obtient en convertissant un nombre flotant de secondes avec la fonction "To_Time_Span". Ensuite, on dit à Ada de ne rien faire jusqu'à cette nouvelle heure. Cela donne Les problèmes de synchronisationLe problème lorsqu'on lance plusieurs tâches, en même temps, c'est la synchonisation : imaginons qu'on dispose d'un robot avec une fonction pour le faire avancer. 2 tâches veulent le faire bouger mais bien sûr, il ne faut pas que les 2 tâches le fasse bouger en même temps. Pour éviter cela, on déclare un Boolean Busy qui sera à True lorsque le robot bouge et à Zero le reste du temps. Chaque tâche aura un code qui ressemblera à ça : if not Busy then Busy = True; Move; Busy = False; end if; Malheureusement, si les 2 tâches s'exécutent en même temps, il se peut que les 2 tâches lisent la valeur de Busy en même temps, elles trouveront donc False toutes les 2. Ensuite, toutes les 2 vont mettre Busy à False puis faire bouger le robot, ce qu'on voulait éviter. La solution en Ada pour éviter ça est les objets "protected" Les protectedUn protected est un objet qui contient des variables (non accessibles directement) et des fonctions/procédures. Le fait que ces procédures soit dans un protected assure qu'une seule tâche peut l'executer à tout moment. Les autres tâches attendent que celle qui est en cours ait fini d'exécuter la procédure. Comme pour les tâches, il faut déclarer les objets protected puis les implémenter. Example: protected Busy is procedure Set_Value (Value : Boolean); function Value return Boolean; private Current_Value : Boolean; end Busy; protected body Busy is procedure Set_Value (Value : Boolean) is begin Current_Value := Value; end Set_Value; function Value return Boolean is begin return Current_Value; end Value; end Busy; Cet exemple de protected ne sert à rien : il faut rajouter une petite fonction : function Can_Move return Boolean is if not Current_Value then Current_Value := True; return True; else return False; end if; end Can_Move; et là, ca compile pas :( : Qu'a cela ne tienne, on va mettre une procédure : procedure Can_Move (Result : out Boolean) is if not Current_Value then Current_Value := True; Result := True; else Result := False; end if; end Can_Move; et voilà, on dispose d'un moyen pour s'assurer qu'une seule tache va déplacer notre robot. Les "entry"Notre protected dispose d'une méthode "Can_Move" qui nous dis si on peut y aller. Maintenant, si on ne peut pas, que fait-on ? On attend un peu et on redemande... Cela n'est pas très optimal : si jamais l'autre tache finie juste après notre teste, il faut attendre quand même. Pour ne pas perdre trop de temps, on va mettre un delai d'attente faible, ce qui va impliquer une plus grosse charge CPU. Pour résoudre ce problème, il existe un méchanisme : les "entry". Une "entry", c'est comme une procédure sauf que pour s'executer, elle attend qu'une condition soit vrai. Dès que la condition devient vrai et qu'il n'y a plus de tache qui execute des fonctions/procédure du protected, le code de l'entry est executé. Exemple: protected Busy is procedure Set_Value (Value : Boolean); function Value return Boolean; entry Wait_Until_Ready; private Current_Value : Boolean; end Busy; protected body Busy is ... entry Wait_Until_Ready when not Current_Value is begin Current_Value := True; end Wait_For_Ready; end Busy;
|
|||




