Joyce es un lenguaje de programación seguro para computación concurrente diseñado por Per Brinch Hansen en la década de 1980. [1] Se basa en el lenguaje secuencial Pascal y los principios de comunicación de procesos secuenciales (CSP). Fue creado para abordar las deficiencias de CSP para ser aplicado como lenguaje de programación, y para proporcionar una herramienta, principalmente para la enseñanza, para la implementación de sistemas de computación distribuida .
Paradigma | concurrente , imperativo , estructurado |
---|---|
Familia | Wirth Pascal |
Diseñada por | Per Brinch Hansen |
Apareció por primera vez | 1987 |
Lanzamiento estable | 1/1987 |
Disciplina de mecanografía | Fuerte |
Influenciado por | |
Comunicación de procesos secuenciales , Pascal , Pascal concurrente | |
Influenciado | |
SuperPascal |
El lenguaje se basa en el concepto de agentes ; Procesos ejecutados simultáneamente que se comunican solo mediante el uso de canales y el paso de mensajes . Los agentes pueden activar subagentes de forma dinámica y recursiva . El desarrollo de Joyce formó la base del lenguaje SuperPascal , también desarrollado por Hansen alrededor de 1993.
Características
Joyce se basa en un pequeño subconjunto de Pascal, ampliado con características inspiradas en CSP para la concurrencia. [2] Las siguientes secciones describen algunas de las características más novedosas que se introdujeron.
Agentes
Un agente es un procedimiento que consta de un conjunto de declaraciones y posiblemente definiciones anidadas de otros agentes. Un agente puede activar dinámicamente subagentes que se ejecutan al mismo tiempo que su creador . Un agente puede terminar solo cuando todos sus subagentes también hayan terminado. Por ejemplo, un agente process2
activa process1
:
agente proceso1 ( x , y : entero ) ; comenzar ... terminar ;agente proceso2 () ; use process1 ; comenzar proceso1 ( 9 , 17 ) ; terminar ;
La activación de un agente crea nuevas instancias de todas las variables locales y el valor de cada parámetro formal se copia en una variable local. Por lo tanto, los agentes no pueden acceder a las variables de otros agentes y solo se les permite comunicarse mediante el uso de canales. Esta restricción evita problemas asociados con el uso de variables compartidas, como las condiciones de carrera .
Comunicación
Los agentes se comunican a través de entidades llamadas canales . Los canales tienen un alfabeto que define el conjunto de símbolos que se pueden transmitir. Los canales se crean dinámicamente y se accede a ellos mediante el uso de variables de puerto . Un tipo de puerto se define mediante un conjunto distinto de símbolos que constituyen su alfabeto. Los símbolos con múltiples valores se definen con un tipo específico. Por ejemplo:
stream = [ int ( entero ) , eos ] ;
El símbolo int(integer)
denota un símbolo de mensaje llamado int
de cualquier valor entero. La segunda declaración de símbolo sin tipo eos
(final de la secuencia) se denomina señal . Una vez que se ha definido un tipo de puerto, se puede declarar una variable de puerto de ese tipo:
out : stream in : stream
Y luego, una entidad de canal, interna al agente que la crea, se puede activar de la siguiente manera:
+ fuera ;
Los símbolos se pueden enviar y recibir en los canales utilizando los operadores de entrada y salida de estilo CSP ?
y !
respectivamente. Una comunicación puede ocurrir solo si hay un agente de recepción que coincide con el agente de envío. El agente receptor debe esperar recibir el tipo de símbolo que se envía. Por ejemplo, el valor 9 seguido del eos
símbolo se envía al puerto out
:
fuera ! int ( 9 ) fuera ! eos
Y se recibe un mensaje entero en una variable de un tipo coincidente, seguido de eos
:
recibido : entero en ? int ( recibido ) en ? eos
Declaraciones de sondeo
Las declaraciones de sondeo se basan en el concepto de CSP de alternativas cautelosas. Una declaración de sondeo se compone de un conjunto de declaraciones, cada una protegida por una declaración de canal de entrada. Cuando se hace coincidir una comunicación entre un agente transmisor y un guardia, se ejecuta el guardia, seguido de la instrucción correspondiente. Por ejemplo:
encuesta en ? X -> x : = x + 1 | en ? Y -> y : = y + 1 final
Donde el puerto in
es monitoreado para las señales X
o Y
, en una comunicación coincidente, las variables correspondientes x
o y
se incrementan.
Seguridad
Joyce fue diseñado para ser un lenguaje seguro en el sentido de que un compilador podría detectar todas las violaciones de las reglas del lenguaje.
Programa de ejemplo
El siguiente es un programa de ejemplo completo, tomado del artículo original que presenta el lenguaje de programación Joyce, [1] implementando un algoritmo para generar números primos basado en una técnica de tamizado para la generación de primos . A un sieve
agente se le envía un flujo de números enteros de su predecesor, siendo el primero un primo. Elimina todos los múltiplos de este primo de la secuencia y activa un sucesor. Esto continúa hasta que la eos
señal se propaga a lo largo del conjunto de tamices.
tamiz de agente ( inp , out : stream ) ; var más : booleano ; x , y : número entero ; succ : corriente ; comenzar encuesta inp ? int ( x ) -> + succ ; tamiz ( succ , fuera ) ; más : = verdadero | inp ? eos -> ¡ fuera ! eos ; más : = final falso ; mientras más hacen encuesta inp ? int ( y ) -> si y mod x <> 0 entonces succ ! int ( y ) | inp ? eos -> ¡ fuera ! int ( x ) ; succ ! eos ; más : = final falso ; terminar ;
El siguiente agente inicializa el conjunto de agentes de tamiz y les introduce un flujo de números enteros entre 3 y 9999.
agentes primos ; utilice generar , tamizar , imprimir ; var a , b : corriente ; comenzar + a ; + b ; generar ( a , 3 , 2 , 4999 ) ; tamiz ( a , b ) ; imprimir ( b ) final ;
Implementación
Asignación de pila
Debido a la ejecución concurrente de los procedimientos del agente, no se puede utilizar un esquema de asignación de pila secuencial convencional ya que los registros de activación de las llamadas del agente no siguen un patrón de último en entrar, primero en salir. En cambio, las relaciones creador-subagente forman una pila estructurada en árbol. Se utiliza un esquema simple para implementar este comportamiento, que funciona asignando nuevos registros de activación en la parte superior de la pila y vinculando los registros de activación de los subagentes con el registro de su creador. Estos registros se liberan solo cuando el agente ha terminado y están en la parte superior de la pila. [3] La efectividad de este esquema depende de la estructura y el comportamiento de un programa, que en algunos casos resultará en un mal uso de la memoria. Se implementó un esquema más efectivo en el lenguaje de Hansen SuperPascal .
Referencias
- ↑ a b Hansen, Brinch (2002). "Joyce: un lenguaje de programación para sistemas distribuidos". En Hansen, Per Brinch (ed.). El origen de la programación concurrente: de los semáforos a las llamadas a procedimientos remotos . Nueva York, Nueva York: Springer. págs. 464–492. doi : 10.1007 / 978-1-4757-3472-0 . ISBN 978-1-4419-2986-0. S2CID 44909506 .
- ^ Hansen, Brinch (junio de 1989). "El informe de la lengua de Joyce" . Software: práctica y experiencia . John Wiley e hijos. 19 (6): 553–578. doi : 10.1002 / spe.4380190606 .
- ^ Hansen, Brinch (junio de 1989). "Una implementación multiprocesador de Joyce" . Software: práctica y experiencia . John Wiley e hijos. 19 (6): 579–592. doi : 10.1002 / spe.4380190606 .
enlaces externos
Sitio web oficial , Archivo Brinch Hansen, un conjunto de sus artículos