“doc” (Col. : Science Sup 17x24) — 2007/7/19 — 18:18 — page 184 — #194
i
i
i
i
i
i
i
i
184
4
• La programmation concurrente dataflow
programmation déclarative restent applicables. C’est une propriété remarquable qui
mérite d’être mieux connue. L’intuition sous-jacente est assez simple. Elle est basée sur
le fait qu’une variable dataflow ne peut être liée qu’à une valeur. La programmation
concurrente avec des variables dataflow gardera donc les bonnes propriétés de la
programmation déclarative.
– Ce qui ne change pas : Le résultat d’un programme est le même, qu’il soit
concurrent ou pas. Mettre une partie quelconque d’un programme dans un fil ne
change pas le résultat.
– Ce qui est nouveau : Le résultat d’un programme peut être calculé de façon incrémentale. Si l’entrée d’un programme concurrent est donnée incrémentalement,
le programme calculera sa sortie incrémentalement aussi.
Donnons un exemple pour concrétiser cette intuition. Considérons un programme
séquentiel qui calcule une liste de carrés à partir d’une liste d’entiers qui est transformée par Map :
fun {Gen L H}
{Delay 100}
if L>H then nil else L|{Gen L+1 H} end
end
Xs={Gen 1 10}
Ys={Map Xs fun {$ X} X * X end}
{Browse Ys}
(L’appel {Delay 100} attend au moins 100 ms avant de continuer.) Nous pouvons en faire un programme concurrent en mettant la génération et la transformation
chacune dans son propre fil :
thread Xs={Gen 1 10} end
thread Ys={Map Xs fun {$ X} X * X end} end
{Browse Ys}
L’instruction thread s end exécute s de façon concurrente. Quelle est la différence entre les versions concurrente et séquentielle ? Le résultat du calcul est le
même dans les deux cas, à savoir [1 4 9 16 ... 81 100]. Dans la version
séquentielle, Gen calcule toute la liste avant le début de Map. Le résultat final est
affiché d’un coup quand le calcul est terminé, après une seconde. Dans la version
concurrente, Gen et Map s’exécutent en même temps. Chaque fois que Gen ajoute
un élément à sa liste, Map calcule immédiatement son carré. Le résultat est affiché au
fur et à mesure que les entiers sont générés, un entier chaque dixième de seconde. Les
listes Xs et Ys, calculées incrémentalement, s’appellent des flots.
La raison pour laquelle cette forme de concurrence est aussi simple est que les programmes n’ont pas de non-déterminisme observable. Un programme dans le modèle
i
i
i
i
i
i
i
i
184
4
• La programmation concurrente dataflow
programmation déclarative restent applicables. C’est une propriété remarquable qui
mérite d’être mieux connue. L’intuition sous-jacente est assez simple. Elle est basée sur
le fait qu’une variable dataflow ne peut être liée qu’à une valeur. La programmation
concurrente avec des variables dataflow gardera donc les bonnes propriétés de la
programmation déclarative.
– Ce qui ne change pas : Le résultat d’un programme est le même, qu’il soit
concurrent ou pas. Mettre une partie quelconque d’un programme dans un fil ne
change pas le résultat.
– Ce qui est nouveau : Le résultat d’un programme peut être calculé de façon incrémentale. Si l’entrée d’un programme concurrent est donnée incrémentalement,
le programme calculera sa sortie incrémentalement aussi.
Donnons un exemple pour concrétiser cette intuition. Considérons un programme
séquentiel qui calcule une liste de carrés à partir d’une liste d’entiers qui est transformée par Map :
fun {Gen L H}
{Delay 100}
if L>H then nil else L|{Gen L+1 H} end
end
Xs={Gen 1 10}
Ys={Map Xs fun {$ X} X * X end}
{Browse Ys}
(L’appel {Delay 100} attend au moins 100 ms avant de continuer.) Nous pouvons en faire un programme concurrent en mettant la génération et la transformation
chacune dans son propre fil :
thread Xs={Gen 1 10} end
thread Ys={Map Xs fun {$ X} X * X end} end
{Browse Ys}
L’instruction thread s end exécute s de façon concurrente. Quelle est la différence entre les versions concurrente et séquentielle ? Le résultat du calcul est le
même dans les deux cas, à savoir [1 4 9 16 ... 81 100]. Dans la version
séquentielle, Gen calcule toute la liste avant le début de Map. Le résultat final est
affiché d’un coup quand le calcul est terminé, après une seconde. Dans la version
concurrente, Gen et Map s’exécutent en même temps. Chaque fois que Gen ajoute
un élément à sa liste, Map calcule immédiatement son carré. Le résultat est affiché au
fur et à mesure que les entiers sont générés, un entier chaque dixième de seconde. Les
listes Xs et Ys, calculées incrémentalement, s’appellent des flots.
La raison pour laquelle cette forme de concurrence est aussi simple est que les programmes n’ont pas de non-déterminisme observable. Un programme dans le modèle
