Articulo de referencia

Patrón de unión

Los patrones de unión proporcionan una forma de escribir programas informáticos concurrentes , paralelos y distribuidos mediante el paso de mensajes . En comparación con el uso ...

Los patrones de unión proporcionan una forma de escribir programas informáticos concurrentes , paralelos y distribuidos mediante el paso de mensajes . En comparación con el uso de hilos y bloqueos, este es un modelo de programación de alto nivel que utiliza un modelo de construcciones de comunicación para abstraer la complejidad del entorno concurrente y permitir la escalabilidad . Se centra en la ejecución de una cadena de mensajes consumidos atómicamente desde un grupo de canales.

Esta plantilla se basa en el cálculo de uniones y utiliza la coincidencia de patrones . Concretamente, esto se logra permitiendo la definición de unión de varias funciones y/o canales mediante la coincidencia de patrones de llamadas y mensajes concurrentes. Se trata de un tipo de patrón de concurrencia, ya que facilita y flexibiliza la comunicación entre estas entidades y su interacción con el paradigma de programación multihilo.

Descripción

El patrón de unión (o acorde en ) es como una supertubería con sincronización y coincidencia. De hecho, este concepto se resume en la coincidencia y unión de un conjunto de mensajes disponibles de diferentes colas de mensajes , para luego manejarlos todos simultáneamente con un solo manejador. [ 1 ] Podría representarse mediante las palabras clave whenpara especificar la primera comunicación que esperamos, con la andunión/emparejamiento de otros canales y la doejecución de algunas tareas con los diferentes mensajes recopilados. Un patrón de unión construido suele tener esta forma:

j.Cuando(a1).Y(a2). ... .Y(an).Hacer(d) 

El argumento a1 de When(a1)puede ser un canal síncrono o asíncrono, o una matriz de canales asíncronos. Cada argumento subsiguiente ai de (para ) debe ser un canal asíncrono. [ 2 ]And(ai)i > 1

Más precisamente, cuando un mensaje coincide con una cadena de patrones vinculados, se ejecuta su controlador (en un nuevo hilo si está en un contexto asíncrono); de lo contrario, el mensaje se pone en cola hasta que se habilita uno de sus patrones. Si hay varias coincidencias, se selecciona un patrón no especificado. [ 3 ]

A diferencia de un controlador de eventos, que atiende uno de varios eventos alternativos a la vez, junto con todos los demás controladores de ese evento, un patrón de unión espera una conjunción de canales y compite por la ejecución con cualquier otro patrón habilitado. [ 4 ]

Este diagrama de flujo muestra cómo se ejecuta el patrón de unión mediante una coincidencia general con diferentes canales (esperar un enlace) y sincroniza los recursos (liberar o bloquear).

El patrón de unión se define mediante un conjunto de canales de cálculo pi x que admiten dos operaciones diferentes: envío y recepción. Necesitamos dos nombres de cálculo de unión para implementarlo: un nombre de canal x para enviar (un mensaje) y un nombre de función x para recibir un valor (una solicitud). El significado de la definición de unión es que una llamada a devuelve un valor que se envió en un canal . Cada vez que las funciones se ejecutan concurrentemente, se activa el proceso de retorno y se sincroniza con otras uniones. [ 5 ]x()x<>

J ::= //patrones de unión | x < y > //patrón de envío de mensajes | x ( y ) //patrón de llamada a función | J | JBIS //sincronización

Desde la perspectiva del cliente, un canal simplemente declara un método con el mismo nombre y firma. El cliente publica un mensaje o realiza una solicitud invocando el canal como un método. Un método de continuación debe esperar hasta que llegue una única solicitud o mensaje a cada uno de los canales que siguen a la cláusula When de la continuación. Si la continuación se ejecuta, los argumentos de cada invocación del canal se extraen de la cola (y, por lo tanto, se consumen) y se transfieren (atómicamente) a los parámetros de la continuación. [ 6 ]

Diagrama de clases del patrón Join

En la mayoría de los casos, el orden de las llamadas síncronas no está garantizado por razones de rendimiento. Finalmente, durante la coincidencia, los mensajes disponibles en la cola podrían ser robados por algún hilo interviniente; de ​​hecho, el hilo despertado podría tener que esperar de nuevo. [ 7 ]

Historia

Cálculo π – 1992

El cálculo π pertenece a la familia de cálculos de procesos , permite formalismos matemáticos para describir y analizar propiedades de computación concurrente mediante el uso de nombres de canales que se comunican a través de los propios canales, y de esta manera es capaz de describir computaciones concurrentes cuya configuración de red puede cambiar durante la computación.

Cálculo combinado – 1993

Los patrones de unión aparecieron por primera vez en el cálculo de unión fundamental de Fournet y Gonthier, un álgebra de procesos asíncrona diseñada para una implementación eficiente en un entorno distribuido. [ 8 ] El cálculo de unión es un cálculo de procesos tan expresivo como el cálculo π completo . Fue desarrollado para proporcionar una base formal para el diseño de lenguajes de programación distribuidos y, por lo tanto, evita intencionalmente las construcciones de comunicación que se encuentran en otros cálculos de procesos, como las comunicaciones de encuentro .

Cálculo de unión distribuido – 1996

El Cálculo de Unión es tanto un cálculo de paso de nombres como un lenguaje central para la programación concurrente y distribuida. [ 9 ] Por eso, en 1996 se creó el Cálculo de Unión Distribuido [ 10 ], basado en el Cálculo de Unión con programación distribuida . Este trabajo utiliza agentes móviles, donde los agentes no son solo programas, sino imágenes centrales de procesos en ejecución con sus capacidades de comunicación.

JoCaml, Funnel y Join Java – 2000

JoCaml [ 11 ] [ 12 ] y Funnel [ 13 ] [ 14 ] son ​​lenguajes funcionales que admiten patrones de unión declarativos. Presentan las ideas para implementar directamente un cálculo de procesos en un entorno funcional.

Otra extensión para Java (no genérico), JoinJava, fue propuesta independientemente por von Itzstein y Kearney. [ 15 ]

C# polifónico – 2002

Cardelli, Benton y Fournet propusieron una versión orientada a objetos de los patrones de unión para C# llamada Polyphonic C# . [ 16 ]

Cω – 2003

Cω es una adaptación del cálculo de unión a un entorno orientado a objetos. [ 17 ] Esta variante de C# polifónico se incluyó en la versión pública de Cω (también conocido como Comega) en 2004.

Scala se une – 2007

Scala Joins es una biblioteca para usar Join-Pattern con Scala en el contexto de la coincidencia de patrones extensible con el fin de integrar uniones en un marco de concurrencia basado en actores existente. [ 18 ]

J. Erlang – 2009

Erlang es un lenguaje que admite de forma nativa el paradigma concurrente, en tiempo real y distribuido. La concurrencia entre procesos era compleja, por eso el proyecto creó un nuevo lenguaje, JErlang ( J significa Join ), basado en el cálculo Join.

El patrón de unión en la literatura clásica de programación.

"Los patrones de unión se pueden utilizar para codificar fácilmente modismos de concurrencia relacionados, como actores y objetos activos." [ 19 ]

utilizando Microsoft.Research.Joins ;clase SymmetricBarrier { public readonly Synchronous . Channel Arrive ;public SymmetricBarrier ( int n ) { // Crear j e inicializar canales ( omitido) JoinPattern pat = j.When ( Arrive ); for ( int i = 1 ; i < n ; i ++ ) { pat = pat.And ( Arrive ) ; } pat.Do ( () = > { } ) ; } }
utilizando Microsoft.Research.Joins ;Unir j = Unir . Crear (); Sincrónico . Canal [] hambriento ; Asíncrono . Canal [] palillo ; j . Inicializar ( salida hambriento , n ); j ​​. Inicializar ( salida palillo , n );for ( int i = 0 ; i < n ; i ++ ) { Asynchronous . Channel left = chopstick [ i ]; Asynchronous . Channel right = chopstick [( i + 1 ) % n ]; j . When ( hungry [ i ]). And ( left ). And ( right ). Do (() => { eat (); left (); right (); // reemplazar palillos }); }
utilizando Microsoft.Research.Joins ;clase Lock { public readonly Synchronous . Channel Acquire ; public readonly Asynchronous . Channel Release ;public Lock () { // Crear j e inicializar canales (omitido) j . When ( Acquire ). And ( Release ). Do (() => { }); Release (); // inicialmente libre } }
utilizando Microsoft.Research.Joins ;clase Buffer < T > { public readonly Asynchronous . Channel < T > Put ; public readonly Synchronous < T > . Channel Get ;public Buffer () { Join j = Join . Create (); // asigna un objeto Join j . Init ( out Put ); // enlaza sus canales j . Init ( out Get ); j ​​. When ( Get ). And ( Put ). Do // registra chord ( t => { return t ; }); } }
utilizando Microsoft.Research.Joins ;clase ReaderWriterLock { privado readonly Asynchronous . Channel idle ; privado readonly Asynchronous . Channel < int > shared ; público readonly Synchronous . Channel AcqR , AcqW , RelR , RelW ;public ReaderWriterLock () { // Crea j e inicializa los canales (omitido) j . When ( AcqR ). And ( idle ). Do (() => shared ( 1 )); j . When ( AcqR ). And ( shared ). Do ( n => shared ( n + 1 )); j . When ( RelR ). And ( shared ). Do ( n => { if ( n == 1 ) { idle (); } else { shared ( n - 1 ); } }); j . When ( AcqW ). And ( idle ). Do (() => { }); j . When ( RelW ). Do (() => idle ()); idle (); // inicialmente libre } }
utilizando Microsoft.Research.Joins ;clase Semáforo { public readonly Synchronous . Channel Acquire ; public readonly Asynchronous . Channel Release ;public Semaphore ( int n ) { // Crea j e inicializa los canales (omitido) j . When ( Acquire ). And ( Release ). Do (() => { }); while ( n > 0 ) { Release (); // inicialmente n libre -- n ; } } }

Características y conceptos fundamentales

  • Cálculo de unión  : La primera aparición del patrón de unión surge con este cálculo de procesos.
  • Paso de mensajes  : El patrón Join funciona con un sistema de paso de mensajes por razones paralelas.
  • Canal  : Los canales se utilizan para sincronizar y pasar mensajes entre hilos que se ejecutan simultáneamente. En general, un canal puede estar involucrado en más de un patrón de unión; cada patrón define una continuación diferente que puede ejecutarse cuando se invoca el canal. [ 6 ]
  • Síncrono  : El patrón de unión podría usar un canal síncrono que devuelve un resultado. La continuación de un patrón síncrono se ejecuta en el hilo del remitente síncrono. [ 6 ]
  • Asíncrono  : También podría usar un canal asíncrono que no devuelva ningún resultado pero acepte argumentos. La continuación de un patrón asíncrono se ejecuta en un hilo recién creado. Un patrón de unión puede ser puramente asíncrono, siempre que su continuación sea una subrutina y su cláusula When solo enumere canales asíncronos. [ 6 ]
  • Combinar síncrono y asíncrono  : La fusión de las declaraciones de búfer síncrono y asíncrono daría como resultado un módulo que admite los dos tipos de comunicación de consumidores. [ 6 ]
  • Planificador  : Existe una planificación entre patrones de unión (por ejemplo, un planificador round-robin , un planificador de primera coincidencia). [ 6 ]
  • Patrones de diseño  : El patrón join es, ante todo, un patrón de comportamiento y de concurrencia.
  • Programación concurrente  : Se ejecuta de forma concurrente.
  • Coincidencia de patrones  : El patrón de unión funciona con tareas de coincidencia.
  • Programación paralela  : Realiza tareas en paralelo.
  • Programación distribuida  : Con este patrón, las tareas podrían estar dispersas en diferentes agentes y entornos.
  • Memoria transaccional de software  : La memoria transaccional de software (STM) es una de las posibles implementaciones para las comunicaciones entre conjuntos.
  • Superposición  : El patrón podría permitir patrones declarados en conjuntos de canales superpuestos.

Dominio de aplicación

Agente móvil

Un agente móvil es un agente de software autónomo con cierta capacidad social y, sobre todo, movilidad. Está compuesto por software y datos que pueden moverse automáticamente entre diferentes ordenadores mientras continúan su ejecución.

Los agentes móviles pueden utilizarse para igualar la concurrencia y la distribución si se emplea el cálculo de unión. Por ello, se creó un nuevo concepto denominado "cálculo de unión distribuido"; se trata de una extensión del cálculo de unión con ubicaciones y primitivas para describir la movilidad. Esta innovación utiliza agentes como procesos en ejecución con sus capacidades de comunicación para permitir la idea de ubicación, que es un sitio físico que expresa la posición real del agente. Gracias al cálculo de unión, una ubicación puede moverse atómicamente a otro sitio. [ 24 ]

Los procesos de un agente se especifican como un conjunto que define su funcionalidad, incluyendo la emisión asíncrona de un mensaje y la migración a otra ubicación. En consecuencia, las ubicaciones se organizan en un árbol para representar el movimiento del agente de forma más sencilla. Con esta representación, una ventaja de esta solución es la posibilidad de crear un modelo de fallo simple. Normalmente, un fallo en un sitio físico provoca el fallo permanente de todas sus ubicaciones. Pero con el cálculo de unión, un problema en una ubicación puede detectarse en cualquier otra ubicación en funcionamiento, lo que permite la recuperación del error. [ 24 ]

El cálculo de unión es el núcleo de un lenguaje de programación distribuido. En particular, la semántica operacional se implementa fácilmente en un entorno distribuido con fallos. Así, el cálculo de unión distribuido trata los nombres de canales y ubicaciones como valores de primera clase con ámbitos léxicos. Una ubicación controla sus propios movimientos y solo puede moverse hacia una ubicación cuyo nombre haya recibido. Esto proporciona una base sólida para el análisis estático y la movilidad segura. Es completo para expresar configuraciones distribuidas. Sin embargo, en ausencia de fallos, la ejecución de procesos es independiente de la distribución. Esta transparencia de ubicación es esencial para el diseño de agentes móviles y muy útil para verificar sus propiedades. [ 24 ]

En 2007, se publicó una extensión del cálculo de unión básico con métodos que hacen que los agentes sean proactivos. Los agentes pueden observar un entorno compartido entre ellos. Con este entorno, es posible definir variables compartidas con todos los agentes (por ejemplo, un servicio de nombres para descubrir agentes entre sí). [ 25 ]

Compilación

Los lenguajes de unión se construyen sobre el cálculo de unión tomado como lenguaje central. Por lo tanto, todo el cálculo se analiza con procesos asíncronos y el patrón de unión proporciona un modelo para sincronizar el resultado. [ 9 ] Para ello, existen dos compiladores:

  • Compilador de unión: Un compilador de un lenguaje llamado "join language". Este lenguaje ha sido creado únicamente para el cálculo de unión.
  • Compilador Jocaml archivado el 1 de octubre de 2005 en Wayback Machine : Un compilador de una extensión de Objectif Caml creada para usar el cálculo de unión.

Este compilador funciona con el mismo sistema, un autómata.

sea ​​A(n) | B() = P(n) y A(n) | C() = Q(n) ;; 

Representa el consumo de mensajes que llegan a un modelo de unión completo. Cada estado es un paso posible para la ejecución del código y cada transición es la recepción de un mensaje para cambiar entre dos pasos. Así, cuando se reciben todos los mensajes, el compilador ejecuta el código de unión del cuerpo correspondiente a la unión del modelo completo.

En el cálculo de unión, los valores básicos son los nombres, como en el ejemplo A, B o C. Los dos compiladores representan estos valores de dos maneras diferentes. El compilador de unión utiliza un vector con dos ranuras: la primera para el nombre en sí y la segunda para una cola de mensajes pendientes. JoCaml utiliza el nombre como un puntero a las definiciones. Estas definiciones almacenan los punteros de los demás nombres con un campo de estado y una estructura de fecha coincidente por mensaje. La diferencia fundamental radica en que, cuando se ejecuta el proceso de verificación, el primero comprueba si todos los nombres son mensajes pendientes listos, mientras que el segundo utiliza solo una variable y accede a las demás para saber si el modelo se ha completado. [ 9 ]

Investigaciones recientes describen el esquema de compilación como la combinación de dos pasos básicos: despacho y reenvío. El diseño y la corrección del despachador se derivan esencialmente de la teoría de coincidencia de patrones, mientras que la inserción de un paso de reenvío interno en las comunicaciones es una idea natural que, intuitivamente, no altera el comportamiento del proceso. Observaron que una implementación directa de la coincidencia de patrones de unión extendida a nivel de tiempo de ejecución complicaría significativamente la gestión de las colas de mensajes, que luego tendrían que ser escaneadas en busca de mensajes coincidentes antes de consumirlos. [ 26 ]

Implementaciones y bibliotecas

Existen muchos usos de los patrones de unión con diferentes lenguajes. Algunos lenguajes utilizan los patrones de unión como base de sus implementaciones, por ejemplo, Polyphonic C# o MC# (archivado el 10/09/2011 en Wayback Machine) , pero otros lenguajes integran el patrón de unión mediante una biblioteca como Scala Joins [ 27 ] para Scala o la biblioteca Joins para VB [ 28 ] . Además, el patrón de unión se utiliza a través de algunos lenguajes como Scheme para actualizar el patrón de unión [ 29 ] .

Únete a Java

Join Java [ 30 ] es un lenguaje basado en el lenguaje de programación Java que permite el uso del cálculo de unión. Introduce tres nuevas construcciones de lenguaje:

  • Los métodos Join se definen mediante dos o más fragmentos Join. Un método Join se ejecutará una vez que se hayan llamado todos los fragmentos del patrón Join. Si el tipo de retorno es un tipo Java estándar, el fragmento principal bloqueará al llamador hasta que el patrón Join se complete y el método se haya ejecutado. Si el tipo de retorno es de tipo señal, el fragmento principal retorna inmediatamente. Todos los fragmentos posteriores son asíncronos, por lo que no bloquearán al llamador.

Ejemplo:

clase JoinExample { int fragment1 () & fragment2 ( int x ) { // Devolverá el valor de x a quien llame a fragment1 return x ; } }
  • Los métodos asíncronos se definen mediante el tipo de retorno `signal`. Este tipo tiene las mismas características que el tipo `void`, con la diferencia de que el método retorna inmediatamente. Cuando se llama a un método asíncrono, se crea un nuevo hilo para ejecutar el cuerpo del método.

Ejemplo:

clase ThreadExample { señal thread ( SomeObject x ) { // Este código se ejecutará en un nuevo hilo } }
  • Modificadores de ordenación

Los fragmentos Join pueden repetirse en múltiples patrones Join, por lo que puede darse el caso de que se completen varios patrones Join al llamar a un fragmento. Esto podría ocurrir en el ejemplo siguiente si se llaman B(), C() y D() y luego A(). El fragmento final A() completa tres de los patrones, por lo que hay tres métodos posibles que pueden ser llamados. El modificador de clase ordered se utiliza aquí para determinar qué método Join se llamará. Por defecto, al usar el modificador de clase unordered, se elige uno de los métodos al azar. Con el modificador ordered, los métodos se priorizan según el orden en que se declaran.

Ejemplo:

clase ordered SimpleJoinPattern { void A () & B () { } void A () & C () { } void A () & D () { } signal D () & E () { } }

El lenguaje más relacionado es el C# polifónico .

JErlang

En la codificación de Erlang , la sincronización entre múltiples procesos no es sencilla. Por eso se creó JErlang, [ 31 ] una extensión de Erlang . La J significa Join (unión). De hecho, para superar esta limitación se implementó JErlang, una extensión de Erlang inspirada en el cálculo de uniones . Las características de este lenguaje son:

  • La operación Joins permite la semántica de primera coincidencia y la posibilidad de tener múltiples patrones conservando el orden de los mensajes.
operación () -> recibir { ok , suma } y { val , X } y { val , Y } -> { suma , X + Y }; { ok , multiplicar } y { val , X } y { val , Y } -> { multiplicar , X * Y }; { ok , restar } y { val , X } y { val , Y } -> { restar , X - Y }; fin fin
  • Los guardias proporcionan filtrado adicional que no se expresa en términos de patrones. Número limitado de expresiones sin efectos secundarios.
recibir { Transacción , M } y { límite , Inferior , Superior } cuando ( Inferior <= M y M <= Superior ) -> confirmar_transacción ( M , Transacción ) fin
  • Con patrones no lineales , los mensajes pueden coincidir con múltiples uniones.
recibir { obtener , X } y { establecer , X } -> { encontrado , 2 , X } fin ... recibir { Pin , id } y { aut. , Pin } y { confirmar , Id } -> realizar_transacción ( Pin , Id ) fin
  • La propagación permite copiar los mensajes correctos en lugar de eliminarlos.
recibir prop ({ sesión , Id }) y { acto , Acción , Id } -> ejecutar_acción ( Acción , Id ); { sesión , Id } y { cerrar sesión , Id } -> cerrar_sesión_usuario ( Id ) fin ... recibir { Pin , id } y { autenticación , Pin } y { confirmación , Id } -> ejecutar_transacción ( Pin , Id ) fin
  • Llamadas síncronas
recibir { aceptar , Pid1 } y { asíncrono , Valor } y { aceptar , Pid2 } -> Pid1 ! { ok , Valor }, Pid2 ! { ok , Valor } fin

C++

Yigong Liu escribió algunas clases para el patrón join, incluyendo todas las herramientas útiles como canales asíncronos y síncronos, acordes , etc. Aparentemente se integró en Boost , pero no parece existir a partir de 2025.

importar std ;plantilla < typename V > clase Buffer : público Joint { público : Async < V > put ; Synchronous < V , void > get ;Buffer () { acorde ( obtener , poner , & Buffer :: acordeBody ); }V chordBody ( void_t g , V p ) { return p ; } };

Este ejemplo demuestra un búfer y una cola de mensajes seguros para subprocesos con las operaciones básicas de inserción y obtención. [ 32 ]

DO#

C# polifónico

C# polifónico es una extensión del lenguaje de programación C#. Introduce un nuevo modelo de concurrencia con métodos síncronos y asíncronos (que devuelven el control a quien los llama) y combinaciones (también conocidas como "patrones de sincronización" o "patrones de unión").

public class Buffer { public String get () & public async put ( String s ) { return s ; } }

Este es un ejemplo sencillo de búfer. [ 33 ]

MC#

MC# Archivado el 10/09/2011 en Wayback Machine El lenguaje es una adaptación del lenguaje C# polifónico para el caso de cálculos distribuidos concurrentes.

public handler Get2 long () & channel c1 ( long x ) & channel c2 ( long y ) { return ( x + y ); }

Este ejemplo demuestra el uso de acordes como herramienta de sincronización.

C# paralelo

Parallel C# se basa en Polyphonic C# y añade algunos conceptos nuevos como métodos móviles y funciones de orden superior.

usando el sistema ;clase Test13 { int Receive () & async Send ( int x ) { return x * x ; }public static void Main ( string [ ] args ) { Test13 t = new Test13 () ; t.Send ( 2 ) ; Console.WriteLine ( t.Receive ( ) ) ; } }

Este ejemplo demuestra cómo usar las uniones. [ 34 ]

añade nuevas características de lenguaje para admitir la programación concurrente (basada en la versión anterior de Polyphonic C# ). La biblioteca de concurrencia Joins para C# y otros lenguajes .NET deriva de este proyecto. [ 35 ] [ 36 ]

Patrones de unión escalables

Es una biblioteca de patrones de unión declarativa y escalable, fácil de usar. A diferencia de la biblioteca Russo, [ 28 ] no tiene bloqueo global. De hecho, funciona con un sistema de mensajes CAS y atómico de comparación e intercambio . La biblioteca [ 37 ] utiliza tres mejoras para el patrón de unión  :

  • Robo de mensajes para recursos no utilizados (permitiendo la intrusión);
  • La cola perezosa ahorra tanto en la asignación como potencialmente en la comunicación entre procesadores al evitar asignar o encolar con una ruta rápida optimista;
  • Un estado "WOKEN"  : garantiza que un llamador síncrono bloqueado se despierte solo una vez.

JoCaml

JoCaml es el primer lenguaje donde se implementó el patrón join. De hecho, al principio todas las implementaciones se compilaban con el compilador de JoCaml. El lenguaje JoCaml es una extensión del lenguaje OCaml . Extiende OCaml con soporte para concurrencia y sincronización, ejecución distribuida de programas y reubicación dinámica de fragmentos de programas activos durante la ejecución. [ 38 ]

tipo de monedas = Nickel | Dime y bebidas = Café | y botones = BCoffee | BTea | BCancel ;;(* def define una cláusula de conjunto de patrón Join * "&" en el lado izquierdo de = significa unión (sincronismo de canal) * "&" en el lado derecho significa: proceso paralelo * synchronous_reply :== "reply" [x] "to" channel_name * los canales síncronos tienen tipos similares a funciones (`a -> `b) * los canales asíncronos tienen tipos (`a Join.chan) * solo la última instrucción en una expresión del lado derecho del patrón puede ser un mensaje asíncrono * 0 en la posición de un mensaje asíncrono significa STOP ("no se envió ningún mensaje" en la terminología CSP).  *)def put ( s ) = print_endline s ; 0 (* STOP *) ;; (* put: string Join.chan *)def servir ( bebida ) = emparejar bebida con Café -> poner ( "Café" ) | -> poner ( "Té" ) ;; (* servir: bebidas Join.chan *)def reembolso ( v ) = let s = Printf . sprintf "Reembolso %d" v in put ( s ) ;; (* reembolso: 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 coino botón ( BCoffee ) y valor ( v ) = dejar should_serve , resto = vender 10 v en ( si should_serve entonces servir ( Café ) sino 0 (*STOP*) ) y valor ( remanente ) y respuesta () al botóno botón ( BTea ) y valor ( v ) = dejar debería_servir , resto = vender 5 v en ( si debería_servir entonces servir ( ) sino 0 (* DETENER *) ) y valor ( resto ) y respuesta () al botóno botón ( BCancel ) y valor ( v ) = reembolso ( v ) y valor ( 0 ) y respuesta () al botón en el valor de aparición ( 0 ) ; moneda , botón (* moneda, botón: int -> unidad *) ;; (* new_vending: bebida Join.chan -> int Join.chan -> (int->unidad)*(int->unidad) *)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 ) ( * deja que aparezca el último mensaje * ) ;;

da

Café Té Reembolso 5 

Hume

Hume [ 39 ] es un lenguaje funcional estricto y fuertemente tipado para plataformas de recursos limitados, con concurrencia basada en paso de mensajes asíncrono, programación de flujo de datos y una sintaxis similar a Haskell .

Hume no proporciona mensajería síncrona.

Envuelve un conjunto de patrones de unión con un canal en común como una caja , enumerando todos los canales en una tupla de entrada y especificando todas las salidas posibles en una tupla de salida .

Cada patrón de unión en el conjunto debe ajustarse al tipo de tupla de entrada de caja que especifica un '*' para los canales no requeridos, dando una expresión cuyo tipo se ajusta a la tupla de salida, marcando con '*' las salidas no alimentadas.

Una cláusula de cable especifica

  1. una tupla de orígenes o fuentes de entrada correspondientes y, opcionalmente, valores iniciales.
  2. una tupla de destinos de salida, que pueden ser canales o sumideros (stdout, ..).

Un cuadro puede especificar manejadores de excepciones con expresiones que se ajusten a la tupla de salida.

data Coins = Nickel | Dime ; data Drinks = Coffee | Tea ; data Buttons = BCoffee | BTea | BCancel ;tipo Int = int 32 ; tipo String = string ; mostrar u = u como string ;caja de café en ( moneda :: Monedas , botón :: Botones , valor :: Entero ) -- canales de entrada salida ( salida_bebida :: Cadena , valor ' :: Entero , salida_reembolso :: Cadena ) -- salidas con nombrecoincidencia -- * comodines para salidas no rellenas y entradas no consumidas ( Nickel , * , v ) -> ( * , v + 5 , * ) | ( Dime , * , v ) -> ( * , v + 10 , * ) | ( * , BCoffee , v ) -> vender Café 10 v | ( * , BTea , v ) -> vender 5 v | ( * , BCancel , v ) -> dejar reembolso u = "Reembolso " ++ mostrar u ++ " \n " en ( * , 0 , reembolso v ) ;vender bebida costo crédito = si crédito >= costo entonces ( servir bebida , crédito - costo , * ) de lo contrario ( * , crédito , * );servir bebida = caso bebida de Café -> "Café \n " -> "Té \n " ;control de caja en ( c :: char ) salida ( coin :: Coins , button :: Buttons ) coincidencia 'n' -> ( Nickel , * ) | 'd' -> ( Dime , * ) | 'c' -> ( * , BCoffee ) | 't' -> ( * , BTea ) | 'x' -> ( * , BCancel ) | _ -> ( * , * ) ;transmitir console_outp a "std_out" ; transmitir console_inp desde "std_in" ;-- cableado del flujo de datoscable coffee -- entradas (orígenes del canal) ( control . coin , control . button , coffee . value ' inicialmente 0 ) -- destinos de salida ( console_outp , coffee . value , console_outp ) ;control de cable ( console_inp ) ( café.moneda , café.botón ) ;

Visual Basic

Concurrent Basic – CB

Una extensión de Visual Basic 9.0 con construcciones de concurrencia asíncrona, llamada Concurrent Basic (o CB), ofrece patrones de unión. CB (basado en trabajos anteriores sobre Polyphonic C#, Cω y la biblioteca Joins) adopta una sintaxis simple similar a la de eventos, familiar para los programadores de VB, permite declarar abstracciones de concurrencia genéricas y proporciona un soporte más natural para la herencia, lo que permite que una subclase amplíe el conjunto de patrones. La clase CB puede declarar un método que se ejecuta cuando se ha producido comunicación en un conjunto particular de canales locales, tanto asíncronos como síncronos, formando un patrón de unión. [ 28 ]

Búfer de móduloPublic Asynchronous Put ( ByVal s As String ) Public Synchronous Take () As StringFunción privada CaseTakeAndPut ( ByVal s As String ) As String _ When Take , Put Return s End FunctionMódulo final

Este ejemplo muestra todas las nuevas palabras clave utilizadas por Concurrent Basic: Asynchronous, Synchronous y When. [ 40 ]

Biblioteca de uniones (C# y VB)

Esta biblioteca es una abstracción de alto nivel del patrón Join que utiliza objetos y genéricos. Los canales son valores delegados especiales de algún objeto Join común (en lugar de métodos). [ 41 ]

utilizando Microsoft.Research.Joins ;clase Buffer { public readonly Asynchronous . Channel < string > Put ; public readonly Synchronous < string > . Channel Get ;public Buffer () { Join join = Join . Create (); join . Initialize ( out Put ); join . Initialize ( out Get ); join . When ( Get ). And ( Put ). Do ( delegate ( string s ) { return s ; }); } }

Este ejemplo muestra cómo usar los métodos del objeto Join. [ 42 ]

Scala

La biblioteca Scala Joins utiliza el patrón Join. Las funcionalidades de coincidencia de patrones de este lenguaje se han generalizado para permitir la independencia de la representación de los objetos utilizados en la coincidencia de patrones. Así, ahora es posible utilizar un nuevo tipo de abstracción en las bibliotecas. La ventaja de los patrones Join es que permiten una especificación declarativa de la sincronización entre diferentes hilos. A menudo, los patrones Join se corresponden estrechamente con una máquina de estados finitos que especifica los estados válidos del objeto.

En Scala, es posible resolver muchos problemas con la coincidencia de patrones y las uniones de Scala, por ejemplo el lector-escritor. [ 27 ]

clase ReaderWriterLock extiende Joins {private val Sharing = new AsyncEvent [ Int ] val Exclusive , ReleaseExclusive = new NullarySyncEvent val Shared , ReleaseShared = new NullarySyncEvent join { case Exclusive () & Sharing ( 0 ) => Exclusive reply case ReleaseExclusive () => { Sharing ( 0 ); ReleaseExclusive reply } case Shared () & Sharing ( n ) => { Sharing ( n + 1 ); Shared reply } case ReleaseShared () & Sharing ( 1 ) => { Sharing ( 0 ); ReleaseShared reply } case ReleaseShared () & Sharing ( n ) => { Sharing ( n - 1 ); ReleaseShared reply } } Sharing ( 0 ) }

En una clase, declaramos eventos en campos regulares. Por lo tanto, es posible usar la construcción `Join` para habilitar la coincidencia de patrones mediante una lista de declaraciones de casos. Esta lista se representa con `=>`, donde cada lado muestra una parte de la declaración. El lado izquierdo es un modelo del patrón `Join` que muestra la combinación de eventos asíncronos y síncronos, y el lado derecho es el cuerpo de `Join`, que se ejecuta una vez completado el modelo.

En Scala, también es posible usar la biblioteca de actores de Scala [ 43 ] con el patrón join. Por ejemplo, un buffer sin límites: [ 27 ]

val Put = new Join1 [ Int ] val Get = new Join class Buffer extends JoinActor { def act () { receive { case Get () & Put ( x ) => Get reply x } } }

Scala Join y Chymyst son implementaciones más recientes del patrón Join, que mejoran la implementación de Scala Joins del Dr. Philipp Haller .

Haskell

Join Language es una implementación del patrón Join en Haskell.

Esquema

Los patrones de unión permiten un nuevo tipo de programación, especialmente para arquitecturas multinúcleo, disponible en muchas situaciones de programación con altos niveles de abstracción. Esto se basa en las protecciones y la propagación. Un ejemplo de esta innovación se ha implementado en Scheme. [ 29 ]

Las protecciones son esenciales para garantizar que solo se actualicen/recuperen los datos con una clave coincidente. La propagación puede cancelar un elemento, leer su contenido y volver a colocarlo en un almacén. Por supuesto, el elemento también está en el almacén durante la lectura. Las protecciones se expresan con variables compartidas. Y así la novedad es que el patrón de unión ahora puede contener partes propagadas y simplificadas. Así que en Scheme, la parte anterior a / se propaga y la parte posterior a / se elimina. El uso del enfoque basado en objetivos es dividir el trabajo en muchas tareas y unir todos los resultados al final con el patrón de unión. Se ha implementado un sistema llamado "MiniJoin" para usar el resultado intermedio para resolver las otras tareas si es posible. Si no es posible, espera la solución de las otras tareas para resolverse a sí mismo. Por lo tanto, la aplicación concurrente del patrón de unión ejecutada en paralelo en una arquitectura multinúcleo no garantiza que la ejecución paralela conduzca a conflictos. Para garantizar esto y un alto grado de paralelismo, se utiliza una memoria transaccional de software (STM) dentro de una estructura de datos concurrente altamente optimizada basada en la comparación e intercambio atómicos (CAS). Esto permite ejecutar muchas operaciones concurrentes en paralelo en una arquitectura multinúcleo. Además, se utiliza una ejecución atómica para evitar el "falso conflicto" entre CAS y STM. [ 29 ]

Otros patrones de diseño similares

El patrón Join no es el único para realizar multitarea, pero es el único que permite la comunicación entre recursos, la sincronización y la unión de diferentes procesos.

  • Patrón de secuencia  : consiste en esperar a que una tarea haya finalizado para pasar a otra (la implementación clásica). [ 44 ]
  • Patrón de división ( división paralela )  : realizar varias tareas en paralelo al mismo tiempo (por ejemplo, MapReduce ). [ 45 ]

Véase también

  • Joins (biblioteca de concurrencia) : Joins es una API de computación concurrente asíncrona de Microsoft Research para .NET Framework.
  • Cálculo de unión : El cálculo de unión se desarrolló para proporcionar una base formal para el diseño de lenguajes de programación distribuidos.
  • Modelo de actores : otra alternativa a los hilos que utiliza el paso de mensajes.

Referencias

  • Cédric, Fournet; Luc, Maranget (15 de agosto de 2006). "El lenguaje Join-Calculus" . Instituto Nacional de Investigación en Informática y Automática . Consultado el 9 de octubre de 2012 .
  • "JoinCalculus" . Cunningham & Cunningham, Inc. 25 de octubre de 2009. Consultado el 9 de octubre de 2012 .
  • Fournet, Cédric; Gonthier, Georges; Levy, Jean-Jacques; Maranget, Luc (1996). "Un cálculo de agentes móviles". CONCUR '96: Teoría de la concurrencia . Apuntes de conferencias sobre informática. vol.  1119. Le Chesnay: teoría de la concurrencia. págs. 406– 421. doi : 10.1007/3-540-61604-7_67 . ISBN  978-3-540-61604-7.
  • Maludzinski, Slawomir; Dobrowolski, Grzegorz (2007). "Entorno del agente y conocimiento en el cálculo de unión distribuida". Sistemas multiagente y aplicaciones V. Notas de clase en ciencias de la computación. Vol.  4696. pp. 298–300 . doi : 10.1007/978-3-540-75254-7_30 . ISBN  978-3-540-75253-0.
  • Russio, Claudio (2006). «La biblioteca de concurrencia Joins». Aspectos prácticos de los lenguajes declarativos . Notas de clase en informática. Vol.  4354. Cambridge: Aspectos prácticos de los lenguajes declarativos. pp. 260–274 . CiteSeerX 10.1.1.187.8792 . doi : 10.1007/978-3-540-69611-7_17 . ISBN   978-3-540-69608-7.
  • Maranget, Luc; Le Fessant, Fabrice (25 de septiembre de 2007). "Compilación de patrones de unión" . Le Chesnay Francia.
  • Haller, Phillip; Van Cutsem, Tom (2008). «Implementación de uniones mediante coincidencia de patrones extensible». Coordination Models and Languages . Lecture Notes in Computer Science. Vol.  5052. Lausana: Coordination Models and Languages. pp. 135–152 . CiteSeerX 10.1.1.210.1242 . doi : 10.1007/978-3-540-68265-3_9 . ISBN   978-3-540-68264-6.
  • Sulzmann, Martin; SL Lam, Edmund. "Patrones de unión paralela con guardas y propagación" . Dinamarca.
  • Fournet, Cédric; Gonthier, Georges (2002). «El cálculo de unión: un lenguaje para la programación móvil distribuida». Semántica aplicada . Notas de clase en ciencias de la computación. Vol.  2395. Springer. pp. 268–332 . CiteSeerX 10.1.1.4.4788 . doi : 10.1007/3-540-45699-6_6 . ISBN   978-3-540-44044-4.
  • Ma, Qin; Maranget, Luc (5 de abril de 2004). "Compilación de coincidencia de patrones en patrones de unión". CONCUR 2004 - Teoría de la concurrencia . Notas de clase en ciencias de la computación. Vol. 3170.  INRIA. págs. 417–431 . CiteSeerX 10.1.1.499.8443 . doi : 10.1007/978-3-540-28644-8_27 . ISBN   978-3-540-22940-7. S2CID 9956643 . 
  • Singh, Satnam (6 de enero de 2007). "Combinadores de orden superior para patrones de unión utilizando STM" .
  • MONSIEUR, Geert (2010), Coordinación basada en patrones en composiciones de servicios basadas en procesos , Lovaina Bélgica: Katholiek Universiteit Leuven
  • Russo, Claudio V. (23 de octubre de 2008). "Patrones de unión para Visual Basic". ACM SIGPLAN Notices . 43 (10): 53– 72. doi : 10.1145/1449955.1449770 .
  • Aaron, Turon; Russo, Claudio V. (27 de octubre de 2011). Patrones de unión escalables (PDF) . Nueva York: Association for Computing Machinery. ISBN 978-1-4503-0940-0.
  • Guzev, Vadim B. (abril de 2008). «C# paralelo: El uso de acordes y funciones de orden superior en el diseño de lenguajes de programación paralelos». Actas de la Conferencia Internacional de 2008 sobre Técnicas y Aplicaciones de Procesamiento Paralelo y Distribuido, PDPTA 2008 (PDF) . CSREA Press. ISBN 978-1601320841.

Notas

  1. Taral Dragon (25 de octubre de 2009). "Únete al cálculo" .
  2. Russo, Claudio V. (23 de octubre de 2008). "Patrones de unión para Visual Basic". ACM SIGPLAN Notices . 43 (10): 10. doi : 10.1145/1449955.1449770 .
  3. "C# paralelo" .
  4. Russo, Claudio V. (27 de octubre de 2008). "Patrones de unión para Visual Basic". ACM SIGPLAN Notices . 43 (10): 2. doi : 10.1145/1449955.1449770 .
  5. Fournet, Cédric; Gonthier, Georges (2002). «El cálculo de unión: un lenguaje para la programación móvil distribuida». Semántica aplicada . Notas de clase en ciencias de la computación. Vol. 2395. Springer. págs. 268–332 . CiteSeerX 10.1.1.4.4788 . doi : 10.1007/3-540-45699-6_6 . ISBN    978-3-540-44044-4.
  6. 1 2 3 4 5 6 Russo, Claudio V. (27 de octubre de 2008). "Patrones de unión para Visual Basic". ACM SIGPLAN Notices . 43 (10): 53– 72. doi : 10.1145/1449955.1449770 .
  7. Russo, Claudio V. (23 de octubre de 2008). "Patrones de unión para Visual Basic". ACM SIGPLAN Notices . 43 (10): 5. doi : 10.1145/1449955.1449770 .
  8. Russo, Claudio V. (23 de octubre de 2008). "Patrones de unión para Visual Basic". ACM SIGPLAN Notices . 43 (10): 18. doi : 10.1145/1449955.1449770 .
  9. 1 2 3 Maranget, Luc; Le Fessant, Fabrice (25 de septiembre de 2007). "Compilación de patrones de unión" . Le Chesnay Francia.
  10. ^ Fournet, Cédric; Gonthier, Georges; Levy, Jean-Jacques; Maranget, Luc (1996). "Un cálculo de agentes móviles". CONCUR '96: Teoría de la concurrencia . Apuntes de conferencias sobre informática. vol. 1119. Le Chesnay: teoría de la concurrencia. págs. 406– 421. doi : 10.1007/3-540-61604-7_67 . ISBN   978-3-540-61604-7.
  11. Fournet, Cedric; Le Fessant, Fabrice; Maranget, Luc; Schmitt, A. (2003). "JoCaml: Un lenguaje para programación concurrente, distribuida y móvil". Programación funcional avanzada . Notas de clase en ciencias de la computación. Vol. 2638. pp. 129–158 . doi : 10.1007/978-3-540-44833-4_5 . ISBN   978-3-540-40132-2.
  12. Conchon, S.; Le Fessant, F. (1999). "Jocaml: Agentes móviles para Objective-Caml". Actas del Primer y Tercer Simposio Internacional sobre Aplicaciones de Sistemas de Agentes y Agentes Móviles . págs. 22–29 . doi : 10.1109/ASAMA.1999.805390 . ISBN  0-7695-0342-X. S2CID 14355301 . 
  13. Odersky, Martin (septiembre de 2000). "Una visión general de las redes funcionales". Escuela de Verano, Caminha, Portugal, septiembre de 2000. 2395 .
  14. Odersky, Martin (2000). "Redes funcionales". Lenguajes y sistemas de programación . Notas de clase en informática. Vol. 1782. págs. 1–25 . doi : 10.1007/3-540-46425-5_1 . ISBN   978-3-540-67262-3.
  15. Itzstein, GS; Kearney, D. (2001). "Join Java: Una semántica de concurrencia alternativa para Java". Informe técnico ACRC-01-001, Universidad del Sur de Australia .
  16. Benton, Nick; Cardelli, Luca; Fournet, Cédric (2002). "Abstracciones modernas de concurrencia para C#". ECOOP 2002 — Programación orientada a objetos . Lecture Notes in Computer Science. Vol. 2374. pp. 415–440 . doi : 10.1007/3-540-47993-7_18 . ISBN   978-3-540-43759-8.
  17. Benton, N.; Cardelli, L. (2004). Abstracciones modernas de concurrencia para C#. ACM Transactions on Programming Languages ​​and Systems . Vol. 26. 
  18. Van Ham, Jurgen M.; Salvaneschi, Guido; Mezini, Mira; Noyé, Jacques (22 de abril de 2014). «JEScala: Coordinación modular con eventos declarativos y uniones» . Actas de la 13.ª conferencia internacional sobre modularidad . MODULARITY '14. Nueva York, NY, EE. UU.: Association for Computing Machinery. pp. 205–216 . doi : 10.1145/2577080.2577082 . ISBN  978-1-4503-2772-5.
  19. Singh, Satnam (6 de enero de 2007). "Combinadores de orden superior para patrones de unión usando STM" . pág. 1. 
  20. 1 2 Aaron, Turon; Russo, Claudio V. (27 de octubre de 2011). Patrones de unión escalables (PDF) . Nueva York: Association for Computing Machinery. pág. 4. ISBN  978-1-4503-0940-0.
  21. Aaron, Turon; Russo, Claudio V. (27 de octubre de 2011). Patrones de unión escalables (PDF) . Nueva York: Association for Computing Machinery. pág. 1. ISBN  978-1-4503-0940-0.
  22. 1 2 Aaron, Turon; Russo, Claudio V. (27 de octubre de 2011). Patrones de unión escalables (PDF) . Nueva York: Association for Computing Machinery. pág. 3. ISBN  978-1-4503-0940-0.
  23. Aaron, Turon; Russo, Claudio V. (27 de octubre de 2011). Patrones de unión escalables (PDF) . Nueva York: Association for Computing Machinery. pág. 2. ISBN  978-1-4503-0940-0.
  24. 1 2 3 Fournet, Cédric; Gonthier, Georges; Levy, Jean-Jacques; Maranget, Luc; Rémy, Didier (1996). "Un cálculo de agentes móviles". CONCUR '96: Teoría de la concurrencia . Apuntes de conferencias sobre informática. vol. 1119. Le Chesnay: teoría de la concurrencia. págs. 406– 421. doi : 10.1007/3-540-61604-7_67 . ISBN   978-3-540-61604-7.
  25. Maludzinski, Slawomir; Dobrowolski, Grzegorz (2007). "Entorno del agente y conocimiento en el cálculo de unión distribuida". Sistemas multiagente y aplicaciones V. Notas de clase en ciencias de la computación. Vol. 4696. pp. 298–300 . doi : 10.1007/978-3-540-75254-7_30 . ISBN   978-3-540-75253-0.
  26. Ma, Qin; Maranget, Luc (5 de abril de 2004). "Compilación de coincidencia de patrones en patrones de unión". CONCUR 2004 - Teoría de la concurrencia . Notas de clase en ciencias de la computación. Vol. 3170. INRIA. págs. 417–431 . CiteSeerX 10.1.1.499.8443 . doi : 10.1007/978-3-540-28644-8_27 . ISBN    978-3-540-22940-7. S2CID 9956643 . 
  27. 1 2 3 Haller, Phillip; Van Cutsem, Tom (2008). "Implementación de uniones mediante coincidencia de patrones extensible". Modelos y lenguajes de coordinación . Notas de clase en informática. Vol. 5052. Lausana: Modelos y lenguajes de coordinación. págs. 135–152 . CiteSeerX 10.1.1.210.1242 . doi : 10.1007/978-3-540-68265-3_9 . ISBN    978-3-540-68264-6.
  28. 1 2 3 Russo, Claudio V. (23 de octubre de 2008). "Patrones de unión para Visual Basic". ACM SIGPLAN Notices . 43 (10): 53– 72. doi : 10.1145/1449955.1449770 .
  29. 1 2 3 Sulzmann, Martin; SL Lam, Edmund. "Patrones de unión paralela con guardas y propagación" . Dinamarca.
  30. von Itzstein, G. Stewart; Kearney, David (2002). Aplicaciones de Join Java . Actas de la Séptima Conferencia de Arquitectura de Sistemas Informáticos de Asia Pacífico ACSAC'2002. Melbourne, Australia, Sociedad Australiana de Computación: 1-20: ACS.{{cite book}}: CS1 mantenimiento: ubicación ( enlace )
  31. Plociniczak, Hubert; Eisenbach, Susan (2010). "JErlang: Erlang con uniones". Coordination Models and Languages . Lecture Notes in Computer Science. Vol. 6116. Springer. pp. 61–75 . Bibcode : 2010LNCS.6116...61P . doi : 10.1007/978-3-642-13414-2_5 . ISBN   978-3-642-13413-5.
  32. Liu, Yigong (2007–2009). "Join – Biblioteca de coordinación y concurrencia de mensajes asíncronos" .
  33. "Introducción al C# polifónico" .
  34. "C# paralelo" . Archivado del original el 26/11/2013.
  35. Hanus, Michael (enero de 2007). The Joins Concurrency Library . Vol. 4354. Springer. ISBN  978-3-540-69608-7.
  36. "Comega" .
  37. Aaron, Turon; Russo, Claudio V. (27 de octubre de 2011). Patrones de unión escalables (PDF) . Nueva York: Association for Computing Machinery. ISBN 978-1-4503-0940-0.
  38. Fournet, Cedric; Le Fessant, Fabrice; Maranget, Luc; Schmitt, Alan (2003). "JoCaml: un lenguaje para programación concurrente, distribuida y móvil" (PDF) . Programación funcional avanzada . Notas de clase en informática. Springer-Verlag. págs. 129–158 . 
  39. Hammond/Michaelson/Sun – Programación de sistemas reactivos en Hume
  40. "Concurrent Basic" . Archivado del original el 25/04/2015.
  41. Russio, Claudio (2006). "La biblioteca de concurrencia Joins". Aspectos prácticos de los lenguajes declarativos . Notas de clase en informática. Vol. 4354. Cambridge: Aspectos prácticos de los lenguajes declarativos. págs. 260–274 . CiteSeerX 10.1.1.187.8792 . doi : 10.1007/978-3-540-69611-7_17 . ISBN    978-3-540-69608-7.
  42. "La biblioteca de concurrencia Joins" .
  43. Haller, Phillip; Odersky, Martin (junio de 2007). «Actores que unifican hilos y eventos» . Modelos y lenguajes de coordinación . Notas de clase en informática. Vol. 4467. Springer. págs. 171–190 . doi : 10.1007/978-3-540-72794-1_10 . ISBN   978-3-540-72793-4.
  44. ^ MONSIEUR, Geert (2010), Coordinación basada en patrones en composiciones de servicios basadas en procesos , Lovaina Bélgica: Katholiek Universiteit Leuven, p. 68 
  45. ^ MONSIEUR, Geert (2010), Coordinación basada en patrones en composiciones de servicios basadas en procesos , Lovaina Bélgica: Katholiek Universiteit Leuven, p. 70 
  • Concurrente Básico
  • Uniones escalables
  • La biblioteca de concurrencia Joins
  • INRIA, Únete a la página principal de Cálculo