Introduction
On appelle concurrence l'indépendance causale entre plusieurs actions,
comme l'exécution de plusieurs instructions en <<même temps>>. C'est
le cas avec les processus de la bibliothèque Unix, présentés
au chapitre précédent.
En effet le système Unix est multi-tâche, il simule sur un ou
plusieurs processeurs l'apparente simultanéïté de l'exécution de
plusieurs instructions.
Sur une machine mono-processeur, il n'y a pas de gain
de performance à l'exécution de plusieurs tâches
simultanément. Néanmoins il est rare, de part l'interaction de
l'utilisateur, qu'une tâche unique est besoin de tout les ressources
de calcul du processeur. Ces processus concurrents peuvent être soit
indépendants les uns des autres soit interagir entre eux.
Dans ce deuxième cas, on retrouve les deux modèles de parallélisme décrits dans l'introduction de cette partie : modèle à mémoire partagée et modèle à mémoire distincte. Dans le cas de partage des ressources mémoire,
il sera nécessaire d'expliciter la synchronisation entre processus. Dans le second cas ce sera
la communication d'informations entre processus qui sera explicitée. Les processus Unix
appartiennent au deuxième cas.
Le langage Objective CAML possède aussi une bibliothèque pour les processus légers
(appelés threads en anglais).
La principale différence entre un processus léger et un processus <<lourd>>, engendré par un fork,
provient
du partage ou du non-partage mémoire entre les différents processus issus du même programme.
Seul le contexte d'exécution diffère entre deux processus légers; le code et la zone mémoire des
données sont partagés. Les processus légers n'améliorent pas les temps d'exécution d'une application.
Leur principal intérêt est de pouvoir exprimer dans un langage de programmation des algorithmes concurrents.
La nature du langage choisi, impératif ou fonctionnel, fait varier le modèle de concurrence.
Pour un langage impératif, comme chaque processus léger peut modifier la mémoire commune,
nous utiliserons le modèle à mémoire partagée.
Pour un langage purement fonctionnel, c'est-à-dire sans effets de bord, et bien que la mémoire soit commune,
les différents calculs s'exécutant sur chaque processus n'interagissent pas sur l'état mémoire d'un autre processus. Pour cela le modèle utilisé est celui à mémoire distincte. L'interaction entre processus
s'effectue par la communication de valeurs entre eux via des canaux de communication.
Le langage Objective CAML implante dans sa bibliothèque sur les processus légers les deux modèles.
Le module Thread permet de lancer de nouveaux processus correspondants à l'appel d'une fonction
sur un argument. Les modules Mutex et Condition apportent les outils de
synchronisation que sont les verrous de zone d'exclusion mutuelle et les attentes sur condition.
Le module Event implante un mode de communication de valeurs du langage par événements.
Ces valeurs peuvent elles-mêmes être fonctionnelles, permettant ainsi
d'échanger entre processus légers des calculs à effectuer. Comme
souvent en Objective CAML il est possible de mélanger les deux modèles.
Un autre intérêt de cette bibliothèque est d'être portable sur les
différents systèmes sur lesquels fonctionnent Objective CAML, à la
différence du fork du module Unix.