xavier-van-de-woestyne-initial
Xavier Van de Woestyne
Functional Programmer

La concurrence et le modèle acteur

03/09/2016

Cet article propose une introduction à la concurrence et au modèle acteur. Un modèle très utilisé dans le minde des applications résilientes.

Depuis plusieurs années, le nombre de processeurs (et d'autres unités de calcul) augmente fortement. Beaucoup de recherches ont étés effectuées pour trouver comment exploiter au mieux ces unités de calcul multiples. Plusieurs formes nouvelles de programmation ont vu le jour. Par exemple, la programmation hétérogène, qui vise à utiliser un matériel spécialisé pour un certain nombre de tâches (comme la carte graphique (et son GPU) pour ne s'occuper que du calcul de rendus visuels complexes). Une autre approche serait de répartir de gros traitements sur différentes instances (ou fragments d'instances) de ces unités de calculs. Toutes ces méthodes s'incrivent dans une forme de programmation que l'on appelle La programmation parallèle.

Contrairement à ce qu'il se dit parfois, la programmation concurrente n'est pas à opposer à la programmation parallèle car elle s'y inscrit. Il ne s'agit que d'une méthode pour permettre à plusieurs actions séquentielles de s'exécuter de manière simultanée.

La programmation concurrente

La programmation parallèle regroupe énormément de manières de paralléliser du code séquentiel. L'idée de la programmation concurrente est de manipuler une collection d'entités indépendantes qui communiquent (idéalement) au moyen d'un bus. De manière un peu formelle, la programmation concurrente admet que dans un programme informatique, il existe plusieurs piles sémantiques (par exemple, des threads ou des processus) qui sont ordonnancées avant d'être exécutées dans une pile d'exécution. Les unités de calcul peuvent être plusieurs processus, plusieurs machines.

Ce modèle de programmation est particulièrement intéressant quand on désire communiquer avec le monde réel qui est, lui même, concurrent. En synthétisant les propos de Joe Armstrong, le créateur de Erlang, un expert en programmation concurrente, on admet que la communication avec le monde réel (où chaque individu, élément, exécute ses actions indépendamment des autres et communique par différents canaux) est beaucoup plus aisé si une correspondance est faite entre le mode d'exécution de notre monde et celui des programme informatique que nous écrivons au travers de notre langage, c'est d'ailleurs un des objectifs de Erlang : "Communiquer simplement avec le monde extérieur en favorisant le traitement concurrent de l'information".

Au-delà d'être en adéquation avec les modes d'exécutions communs de notre monde, comme, via notre matériel, un langage concurrent produira du code capable de se distribuer sur plusieurs unités de calcul, la performance des applications qui doivent effectuer certaines typologies de gros calculs/traitements sera, logiquement, accrue.

La programmation concurrente est accessible au niveau logiciel et peut-être, à priori, implantée dans n'importe quel langage. Cependant, Erlang et Go sont deux exemples de langages intégrant la concurrence comme un élément de conception important. Ils sont donc deux candidats idéals dans de multiples domaines demandant une interaction avec le monde réel ou une grande disponibilité. Comme ils accordent tous deux une importance capitale à la concurrence, ils partagent certains traits, cependant, il existe plusieurs manières de proposer des mécanismes concurrents et les langages présentent tout de même certaines différences.

Le modèle acteur

Bien qu'il existe plusieurs manière d'implémenter un modèle concurrent dans un langage de programmation, une approche commune est d'utiliser le modèle acteur. C'est un trait que partagent Go et Erlang. Un autre utilisateur réputé des acteurs est le langage Scala qui intègre un modèle acteur assez puissant (initialement léger mais enrichi par la bibliothèque Akka). En OCaml, il faut passer par une bibliothèque tierce (tout de même écrite en pure OCaml, sans connexion avec le système d'exploitation).

Historiquement, le modèle acteur est un modèle mathématique, proposé par Carl Hewitt dans le début des années 1970 pour manipuler des preuves formelles et des modèles dans un robot.

La notion d'acteur est à prendre comme celle de l'objet, soit une entité défini par quelques caractéristiques. On considère les acteurs comme les seules fonctions primitives nécéssaires pour la programmation concurrente. Les acteurs communiquent par envoi/réceptions de messages. En répondant à un message, un acteur peut effectuer un calcul, instancier d'autres acteurs ou envoyer d'autres messages. (Il existe une certaine homologie entre les acteurs et les objets qui eux aussi communiquent par envoi/réception de message...)

L'informatique théorique (et donc par extension, l'informatique industrielle, avec quelques décéni... années de retard, aussi) a aussi été teinté par ce modèle, en effet, le modèle acteur sera une des sources principales pour le Pi-calcul, un langage théorique servant à étudier l'informatique parallèle et distribuée. Il est souvent présenté comme l'un des enfants spirituels du Lambda-calcul qui visait, lui, à étudier l'informatique classique. Comme le modèle acteur est à la base de beaucoup de langages et d'architectures concurrents. Il est aussi la base du Cloud-computing (où les acteurs seraient les cœurs de calcul).

Le modèle acteur proposé par Erlang est souvent présenté comme une inspiration directe de celui de Carl Hewitt, cependant, les auteurs du langages affirment (et nous les croyons) qu'ils ne connaissaient pas cette proposition (enfermée dans le monde académique) et que les ressemblances sont apparues de manière organique en fonction de leurs besoins.

Un des apports principaux du modèle acteur est que, quand il est implémenté dans un langage, il fournit une abstraction sur des mécanismes liés à l'exécution simultanée. Cette abstraction permet généralement de s'affranchir de concepts/outils complexes, comme par exemple la synchronisation par verrou.

Un modèle aux implémentations multiples

Nous avons souligné une ressemblance conceptuelle avec le modèle objet, notamment sur la terminologie. Une autre ressemblance pourrait être la liberté d'interprétation du concept d'acteur. En effet, la définition des acteurs, comme entités concurrentes, est présentée au moyen de caractéristiques, ce qui fait que l'implémentation et la sémantique d'une bibliothèque (ou d'un langage) concurrente peut être très variable, comme pour les différences entre les langages objets (je vous invite à comparer Smalltalk et C++ par exemple).

Dans un prochain article, nous choisirons deux langages concurrents qui utilisent les acteurs et nous tâcherons d'en montrer les différences pour illustrer le propos de ce paragraphe.

Conclusion

L'enjeu de cet article était de présenter sommairement l'idée derrière la programmation concurrente au moyen d'acteurs. Il permettra d'introduire d'autres articles qui traiteront de langages et de technologies concurrents.

Une autre idée était de préciser le lien qui unit la programmation parallèle de la programmation concurrente. Pour résumer, la concurrence implique le parallélisme mais la concurrence n'est pas équivalente au parallélisme.

A bientôt pour de prochains articles.