En programmation concurrente, Communicating sequential processes (CSP) est une algèbre de processus permettant de modéliser l'interaction de systèmes.
CSP intègre un mécanisme de synchronisation basé sur le principe du rendez-vous (détaillé plus loin au travers de la commande d'entrée/sortie). Combinant ce mécanisme à une syntaxe simple et concise, CSP permet alors l'implémentation rapide des paradigmes classiques de la concurrence, tels que producteurs/consommateurs ou lecteurs/écrivains. Ce n'est pas un langage de programmation complet.
CSP fut décrit en premier par C. A. R. Hoare dans un article de 1978 , mais a depuis évolué de façon substantielle. CSP a été mis en pratique industriellement comme un outil de spécification formelle de l'exécution concurrente de systèmes variés — tels que le T9000 Transputer ou un système informatique de transaction commerciale sécurisé. C'est un champ de recherche toujours actif.
Un programme CSP se présente sous la forme d'une suite de commandes et de déclarations de variable séparées par des points-virgule :
x: integer; y: integer; x:= 4; ...
Hoare distingue alors deux types de commandes :
Les commandes d'entrée/sortie, parallèle, répétitive et alternative seront détaillées par la suite. La commande nulle, par définition, ne fait rien. Elle permet juste de combler les blocs d'instructions vides. La commande d'affectation a quant à elle une syntaxe classique variable := valeur :
x:= 5
L'échec d'une commande (par exemple, dans le cas d'une commande d'entrée/sortie, si le processus visé n'existe pas) entraîne l'échec du processus ou de la commande structurée qui la contient (l'échec d'une commande peut donc entraîner la fin du programme). Notons le cas particulier d'une répétitive dont l'échec d'une commande interne entraîne la terminaison et non la faillite (cf. partie La commande répétitive).
Un échec n'est donc pas une erreur en soi.
Une notion de signal a aussi été introduite en CSP. Un signal est en quelque sorte une variable complexe (ou structurée) composé d'un constructeur (un identifiant libre) ainsi que d'un ensemble de valeurs. Les valeurs peuvent être soit de type élémentaire (entier, chaîne de caractères, etc.) soit d'autres signaux.
Exemples :
Notons aussi qu'un signal peut être affecté à une variable (exemple : x := p (4)), et peut aussi être la cible d'une affectation. Cela permet alors des affectations du type (x, y) := (y, x).
On retrouve souvent la syntaxe PROCESSUS == liste d'instructions pour définir un processus à l'extérieur d'une commande parallèle, dans le seul but de clarifier le code. Exemple :
PREMIER == x: integer:= 5; ... SECOND == msg: string; ... MAIN == [ premier:: PREMIER || second:: SECOND ]
La liste d'instructions MAIN est alors celle executée au lancement du programme.
Pour afficher un message à l'écran, on utilise usuellement la commande :
print (message)
x:= random (debut, fin)
Permet de prendre un nombre au hasard compri dans l'intervalle [debut, fin]
sleep (tps)
Stoppe le processus qui l'exécute pendant tps millisecondes. Permet de simuler des temps d'attente, etc.
On utilise communément la syntaxe :
define CONSTANTE valeur
Exemple :
define PI 3.1415