Ce modèle est basé sur le calcul de jointure et utilise la correspondance de motifs . Concrètement, il permet la définition conjointe de plusieurs fonctions et/ou canaux en faisant correspondre les modèles d'appels et de messages concurrents. Il s'agit d'un type de modèle de concurrence car il facilite et assouplit la communication entre ces entités et leur permet de gérer plus facilement le paradigme de programmation multithread.
Cω ) s'apparente à un super pipeline avec synchronisation et appariement. Concrètement, ce concept consiste à apparier et joindre un ensemble de messages provenant de différentes files d'attente , puis à les traiter simultanément par un seul gestionnaire. Il peut être représenté par les mots-clés suivants : `join`Ce diagramme de flux montre comment le modèle de jonction est exécuté par une correspondance générale avec différents canaux (attendre un accord) et synchronise les ressources (libre ou verrouillée). Le modèle de jointure est défini par un ensemble de canaux de pi-calcul x qui prennent en charge deux opérations différentes : l’envoi et la réception. Pour l’implémenter, deux noms de calcul de jointure sont nécessaires : un nom de canal x pour l’envoi (un message) et un nom de fonction x pour la réception d’une valeur (une requête). La définition de la jointure signifie qu’un appel à x renvoie une valeur envoyée sur un canal . Chaque appel simultané de fonctions déclenche le processus de retour et se synchronise avec les autres jointures. Diagramme de classes du modèle Join
Dans la plupart des cas, l'ordre des appels synchrones n'est pas garanti pour des raisons de performance. Enfin, pendant la correspondance, les messages disponibles dans la file d'attente peuvent être récupérés par un thread intermédiaire ; en effet, le thread réveillé peut devoir attendre à nouveau.
Histoire
π-calcul – 1992
Le π-calcul appartient à la famille des calculs de processus , permet des formalismes mathématiques pour décrire et analyser les propriétés du calcul concurrent en utilisant les noms de canaux à communiquer le long des canaux eux-mêmes, et de cette manière il est capable de décrire des calculs concurrents dont la configuration du réseau peut changer pendant le calcul.
Join-Calculus – 1993
Les modèles de jointure sont apparus pour la première fois dans le calcul de jointure fondamental de Fournet et Gonthier, une algèbre de processus asynchrone conçue pour une implémentation efficace dans un environnement distribué. Le calcul de jointure est un calcul de processus aussi expressif que le π-calcul complet . Il a été développé pour fournir une base formelle à la conception de langages de programmation distribués et, par conséquent, évite intentionnellement les constructions de communication présentes dans d'autres calculs de processus, telles que les communications de rendez-vous .
Jointure distribuée - Calcul différentiel – 1996
Le Join-Calculus est à la fois un calcul de passage de noms et un langage fondamental pour la programmation concurrente et distribuée. C'est pourquoi le Join-Calculus distribué , basé sur le Join-Calculus et intégrant la programmation distribuée, a été créé en 1996. Ce travail utilise des agents mobiles, ces agents étant non seulement des programmes, mais aussi des représentations au cœur des processus en cours d'exécution, dotées de leurs capacités de communication.
JoCaml, Funnel et Join Java – 2000
JoCaml et Funnel sont des langages fonctionnels prenant en charge les modèles de jointure déclaratifs. Ils présentent les idées permettant d'implémenter directement un calcul de processus dans un cadre fonctionnel.
Une autre extension de Java (non générique), JoinJava, a été proposée indépendamment par von Itzstein et Kearney.
Do# polyphonique – 2002
Cardelli, Benton et Fournet ont proposé une version orientée objet des modèles de jointure pour C# appelée Polyphonic C# .
Cω – 2003
Cω est une adaptation du calcul de jointure à un cadre orienté objet. Cette variante de C# polyphonique a été incluse dans la version publique de Cω (alias Comega) en 2004.
Jointures Scala – 2007
Scala Joins est une bibliothèque permettant d'utiliser le modèle Join avec Scala dans le contexte de la correspondance de modèles extensible afin d'intégrer les jointures dans un framework de concurrence basé sur les acteurs existant.
JErlang – 2009
Erlang est un langage qui prend en charge nativement le paradigme concurrent, temps réel et distribué. La gestion de la concurrence entre les processus étant complexe, le projet a développé un nouveau langage, JErlang ( J pour Join ), basé sur le calcul de jointure.
Modèle de jointure dans la littérature classique de programmation
"Les modèles de jointure peuvent être utilisés pour encoder facilement des idiomes de concurrence connexes comme les acteurs et les objets actifs."
utilisation de Microsoft.Research.Joins ;class Lock { public readonly Synchronous . Channel Acquire ; public readonly Asynchronous . Channel Release ;public Lock () { // Créer j et initialiser les canaux (omis) j.When ( Acquire ) .And ( Release ).Do ( () => { } ); Release (); // initialement libre } }
utilisation de Microsoft.Research.Joins ;classe Semaphore { public readonly Synchronous . Channel Acquire ; public readonly Asynchronous . Channel Release ;public Semaphore ( int n ) { // Créer j et initialiser les canaux (omis) j.When ( Acquire ).And ( Release ) .Do ( () => { } ); while ( n > 0 ) { Release (); // n initialement libre -- n ; } } }
Caractéristiques et concepts fondamentaux
- Calcul de jointure : La première apparition du modèle de jointure se fait avec ce calcul de processus.
- Transmission de messages : Le modèle Join fonctionne avec un système de transmission de messages pour des raisons de parallélisme.
- Canal : Les canaux servent à synchroniser et à transmettre des messages entre des threads s’exécutant simultanément. En général, un canal peut être impliqué dans plusieurs modèles de jonction ; chaque modèle définit une continuation différente qui peut s’exécuter lorsque le canal est invoqué.
- Synchrone : Le modèle de jointure peut utiliser un canal synchrone qui renvoie un résultat. La continuation d’un modèle synchrone s’exécute dans le thread de l’émetteur synchrone.
- Asynchrone : Il peut également utiliser un canal asynchrone qui ne renvoie aucun résultat mais prend des arguments. La continuation d’un motif asynchrone s’exécute dans un nouveau thread. Un motif de jointure peut être purement asynchrone, à condition que sa continuation soit une sous-routine et que sa clause When ne liste que des canaux asynchrones.
- Combinaison des modes synchrone et asynchrone : La fusion des déclarations des tampons synchrone et asynchrone permettrait d’obtenir un module prenant en charge les deux types de communication des consommateurs.
- Planificateur : Il existe une planification entre les modèles de jointure (par exemple, un planificateur round-robin , un planificateur de première correspondance).
- Modèles de conception : Le modèle de jointure est avant tout un modèle comportemental et un modèle de concurrence.
- Programmation concurrente : Elle s'exécute de manière concurrente.
- Correspondance de modèles : Le modèle de jointure fonctionne avec des tâches de correspondance.
- Programmation parallèle : Elle exécute les tâches en parallèle.
- Programmation distribuée : avec ce modèle, les tâches peuvent être réparties sur différents agents et environnements.
- Mémoire transactionnelle logicielle : La mémoire transactionnelle logicielle (STM) est l'une des implémentations possibles pour les communications entre les articulations.
- Chevauchement : Le modèle peut autoriser des modèles déclarés sur des ensembles de canaux qui se chevauchent.
Domaine d'application
Agent mobile
Un agent mobile est un agent logiciel autonome doté de certaines capacités sociales et, surtout, de mobilité. Il est composé de logiciels et de données qui peuvent se déplacer automatiquement entre différents ordinateurs tout en poursuivant leur exécution.
Les agents mobiles permettent de gérer la concurrence et la distribution grâce au calcul de jointure. C’est pourquoi un nouveau concept, le « calcul de jointure distribué », a été créé ; il s’agit d’une extension du calcul de jointure intégrant des emplacements et des primitives pour décrire la mobilité. Cette innovation considère les agents comme des processus en cours d’exécution, leurs capacités de communication permettant de définir un emplacement, c’est-à-dire un site physique exprimant la position réelle de l’agent. Grâce au calcul de jointure, un emplacement peut être déplacé atomiquement vers un autre site.
Les processus d'un agent sont définis par un ensemble qui caractérise sa fonctionnalité, notamment l'émission asynchrone de messages et la migration vers un autre emplacement. Par conséquent, les emplacements sont organisés sous forme d'arbre afin de faciliter la représentation des déplacements de l'agent. Cette représentation offre l'avantage de permettre la création d'un modèle de défaillance simple. Habituellement, la panne d'un site physique entraîne la défaillance permanente de tous ses emplacements. Cependant, grâce au calcul de jointure, un problème affectant un emplacement peut être détecté sur n'importe quel autre emplacement opérationnel, permettant ainsi la récupération après incident.
Wayback Machine : Un compilateur d'une extension d'Objectif Caml créé pour utiliser le calcul de jointure.Ces deux compilateurs fonctionnent avec le même système, un automate.
| JErlang | CB | Rejoins la bibliothèque | Do# polyphonique | C# parallèle | Cω | Jointures Scala | Fa# | Schème | Rejoignez Java | Hume | JoCaml | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Motifs assortis | langage de programmation Java permettant l'utilisation du calcul de jointure. Il introduit trois nouvelles constructions de langage :
Exemple: C# polyphonique . JErlangEn Erlang , la synchronisation de plusieurs processus n'est pas simple. C'est pourquoi JErlang , une extension d' Erlang , a été créée. Le J signifie « Join ». En effet, pour pallier cette limitation, JErlang a été implémentée : il s'agit d'une extension d' Erlang inspirée du calcul de jointure . Les caractéristiques de ce langage sont les suivantes :
receive {ok, sum} and {val, X} and {val, Y} -> {sum, X + Y}; {ok, mult} and {val, X} and {val, Y} -> {mult, X * Y}; {ok, sub} and {val, X} and {val, Y} -> {sub, X - Y}; end end " opération () -> recevoir { ok , somme } et { val , X } et { val , Y } -> { somme , X + Y }; { ok , multiplicateur } et { val , X } et { val , Y } -> { multiplicateur , X * Y }; { ok , sous- } et { val , X } et { val , Y } -> { sous- , X - Y }; fin fin
asynchrones et synchrones, les accords , etc. Il semble qu'il ait été intégré à Boost , mais il ne semble plus exister en 2025. C# polyphonique est une extension du langage de programmation C#. Il introduit un nouveau modèle de concurrence avec des méthodes et des accords synchrones et asynchrones (qui rendent le contrôle à l'appelant) (également appelés « modèles de synchronisation » ou « modèles de jonction »). Wayback Machine. Le langage machine est une adaptation du langage C# polyphonique pour le cas des calculs distribués concurrents. Cω ajoute de nouvelles fonctionnalités au langage pour prendre en charge la programmation concurrente (basée sur le C# polyphonique précédent ). La bibliothèque de concurrence Joins pour C# et d'autres langages .NET est dérivée de ce projet. Modèles de jointure évolutifsIl s'agit d'une bibliothèque de modèles de jointure déclarative, facile à utiliser et évolutive. Contrairement à la bibliothèque Russo , elle ne comporte pas de verrou global. En effet, elle fonctionne avec un système CAS de comparaison et d'échange et un système de messages atomiques. La bibliothèque utilise trois améliorations pour le modèle de jointure :
JoCamlJoCaml est le premier langage où le modèle de jointure a été implémenté. En effet, à l'origine, toutes les implémentations étaient compilées avec le compilateur JoCaml. Le langage JoCaml est une extension du langage OCaml . Il étend OCaml en y ajoutant la prise en charge de la concurrence et de la synchronisation, l'exécution distribuée des programmes et le déplacement dynamique des fragments de programme actifs pendant l'exécution. `b) * asynchronous channels have types (`a Join.chan) * only the last statement in a pattern rhs expression can be an asynchronous message * 0 in an asynchronous message position means STOP (\"no sent message\" in CSP terminology). *) def put(s) = print_endline s ; 0 (* STOP *) ;; (* put: string Join.chan *) def serve(drink) = match drink with Coffee -> put(\"Cofee\") | Tea -> put(\"Tea\") ;; (* serve: drinks Join.chan *) def refund(v) = let s = Printf.sprintf \"Refund %d\" v in put(s) ;; (* refund: int Join.chan *) let new_vending serve refund = let vend (cost:int) (credit:int) = if credit >= cost then (true, credit - cost) else (false, credit) in def coin(Nickel) & value(v) = value(v+5) & reply () to coin or coin(Dime) & value(v) = value(v+10) & reply () to coin or button(BCoffee) & value(v) = let should_serve, remainder = vend 10 v in (if should_serve then serve(Coffee) else 0 (* STOP *)) & value(remainder) & reply () to button or button(BTea) & value(v) = let should_serve, remainder = vend 5 v in (if should_serve then serve(Tea) else 0 (* STOP *)) & value(remainder) & reply () to button or button(BCancel) & value(v) = refund( v) & value(0) & reply () to button in spawn value(0) ; coin, button (* coin, button: int -> unit *) ;; (* new_vending: drink Join.chan -> int Join.chan -> (int->unit)*(int->unit) *) let ccoin, cbutton = new_vending serve refund in ccoin(Nickel); ccoin(Nickel); ccoin(Dime); Unix.sleep(1); cbutton(BCoffee); Unix.sleep(1); cbutton(BTea); Unix.sleep(1); cbutton(BCancel); Unix.sleep(1) (* let the last message show up *) ;; " pièces de monnaie = Nickel | Dime et boissons = Café | Thé et boutons = BCoffee | BTea | BCancel ;;(* def définit une clause d'ensemble de modèles de jointure * "&" à gauche du = signifie jointure (synchronisation des canaux) * "&" à droite signifie : traitement parallèle * synchronous_reply :== "reply" [x] "to" channel_name * Les canaux synchrones ont des types de type fonction (`a -> `b) * Les canaux asynchrones ont des types (`a Join.chan) * Seule la dernière instruction d'une expression de modèle à droite peut être un message asynchrone * 0 à la position d'un message asynchrone signifie STOP (« aucun message envoyé » dans la terminologie CSP). *)def put ( s ) = print_endline s ; 0 (* STOP *) ; (* put: string Join.chan *)def serve ( drink ) = match drink with Coffee- > put ( "Coffee" ) | Tea- > put ( "Tea" ) ;; (* serve: drinks Join.chan *)def refund ( v ) = let s = Printf.sprintf "Remboursement %d" v in put(s) ;; ( * refund : int Join.chan *)let new_vending serve refund = let vend ( cost : int ) ( credit : int ) = if credit >= cost then ( true , credit - cost ) else ( false , credit ) in def coin ( Nickel ) & value ( v ) = value ( v + 5 ) & reply () to coin or coin ( Dime ) & value ( v ) = value ( v + 10 ) & reply () to coinou bouton ( BCoffee ) & valeur ( v ) = soit devrait_servir , reste = vendre 10 v dans ( si devrait_servir alors servir ( Café ) sinon 0 (* STOP *) ) & valeur ( reste ) & répondre () au boutonou bouton ( BTea ) & valeur ( v ) = soit devrait_servir , reste = vendre 5 v dans ( si devrait_servir alors servir ( Thé ) sinon 0 (* STOP *) ) & valeur ( reste ) & réponse () au boutonou bouton ( BCancel ) & valeur ( v ) = remboursement ( v ) & valeur ( 0 ) & réponse () au bouton dans spawn valeur ( 0 ) ; pièce , bouton (* pièce, bouton : int -> unité *) ;; (* nouveau_distributeur : boisson Join.chan -> int Join.chan -> (int->unité)*(int->unité) *)let ccoin , cbutton = new_vending serve refund in ccoin ( Nickel ); ccoin ( Nickel ); ccoin ( Dime ); Unix . sleep ( 1 ); cbutton ( BCoffee ); Unix . sleep ( 1 ); cbutton ( BTea ); Unix . sleep ( 1 ); cbutton ( BCancel ); Unix . sleep ( 1 ) (* laisser le dernier message s'afficher *) ;; donne Hume est un langage fonctionnel strict et fortement typé pour les plateformes aux ressources limitées, avec une concurrence basée sur le passage de messages asynchrones, la programmation de flux de données et une syntaxe de type Haskell . Visual BasicConcurrent Basic – CBConcurrent Basic (CB), une extension de Visual Basic 9.0 intégrant des constructions de concurrence asynchrone, propose les modèles de jointure. CB (s'appuyant sur des travaux antérieurs concernant Polyphonic C#, Cω et la bibliothèque Joins) adopte une syntaxe simple, de type événementiel, familière aux programmeurs VB. Elle permet de déclarer des abstractions de concurrence génériques et offre une prise en charge plus naturelle de l'héritage, permettant ainsi à une sous-classe d'enrichir l'ensemble des modèles. Une classe CB peut déclarer une méthode à exécuter lorsqu'une communication a eu lieu sur un ensemble particulier de canaux locaux, asynchrones et synchrones, formant ainsi un modèle de jointure. de correspondance de motifs de ce langage ont été généralisés afin de permettre l'indépendance de la représentation des objets utilisés. Il est donc désormais possible d'utiliser un nouveau type d'abstraction dans les bibliothèques. MapReduce ). |