Hace dos años ya, estuve explorando Microsoft Robotics, y su librería CCR (Concurrency and Coordination). Esta tiene la implementación una port: podemos enviar un objeto por el port, y recibirlo y procesarlo en otra pieza de código, que puede ejecutarse en otro hilo de ejecución. También tiene la capacidad de ejecutar ambas partes en diferentes máquinas, una forma de conectar aplicaciones distribuidas. Yo escribí sobre el tema en:
Distributed Agents using DSS/VPL
Agentes Distribuidos usando DSS/VPL
Agentes Distribuidos y Fractales usando DSS/VPL
Genetic Algorithms with AjAgents and Concurrency and Coordination Runtime (CCR)
Algoritmos Genéticos con AjAgents y Concurrency and Coordination Runtime (CCR)
CCR posts (English)
Posts sobre CCR en español
Todo esto, me llevó a encontrarme con el concepto de canal: Channel programming (Wikipedia) y este año, leí sobre el nuevo lenguaje de Google, el lenguaje Go: http://golang.org. Pueden leer sobre Go y sus capacidades de manejo de concurrencia (go routines, channels) en: http://golang.org/doc/go_tutorial.html#tmp_346
También comencé a leer sobre proyecto Axum de Microsoft: http://en.wikipedia.org/wiki/Axum_%28programming_language%29
Con toda esta base, el último sábado agregué soporte de canales y goroutines en mi intérprete AjSharp (otros posts AjSharp interpreter). Pueden bajar y ver la versión actual desde http://code.google.com/p/ajcodekatas en trunk/AjLanguage
Primero, agregué un tipo nativo .NET Channel (a mejorar: agregar soporte para que el canal pueda soportar varios send y receive desde más de un thread):
public class Channel { private AutoResetEvent sethandle = new AutoResetEvent(false); private AutoResetEvent gethandle = new AutoResetEvent(false); private object value; public void Send(object value) { this.gethandle.WaitOne(); this.value = value; this.sethandle.Set(); } public object Receive() { this.gethandle.Set(); this.sethandle.WaitOne(); object result = this.value; return result; } }Cuando se envía un objeto a un canal, el thread que lo envía se bloquea hasta que otro thread lea el canal (pienso agregar un QueueChannel, donde se puedan enviar varios objetos, a guardar en una cola, sin para los threads; supongo que la cola tendrá un tamaño limitado, para ir auto-coordinando los productores y consumidores de objetos del canal).
Siguiendo las ideas de goroutines en el lenguaje Go, agregué un nuevo comando en AjSharp: go <command> (ok, no mucha creatividad aquí… ;-)… igual hay que aclarar que los goruotines en Go tienen muchas más características que las que implemento acá). Esta nueva palabra lanza el comando en un thread separado, que comparte las variables del original, como en este ejemplo (recordemos que AjSharp tiene acceso a los objetos y clases nativas de .NET):
handle = new System.Threading.AutoResetEvent(false); one = 0; go { one = 1; handle.Set(); } handle.WaitOne(); result = one;Todo esto se agregó a la máquina de ejecución de AjSharp (por ejemplo, Channel es un tipo ya declarado dentro de la máquina, sin necesidad de usar el namespace completo), podemos usar entonces:
channel = new Channel(); go channel.Send(10); result = channel.Receive();
Luego de tener esto andando, modifiqué algo más. Fue simple agregar “syntax sugar” al parser de AjSharp para que
<- channel
sea igual a
channel.Receive()
y que
channel <- value;
sea una forma de escribir:
channel.Send(value);
Entonces, el ejemplo anterior se puede escribir como:
channel = new Channel(); go channel <- 10; result = <- channel;
En otro post, describiré algunos usos de estas características, con algún detalle de implementación. Ver el código actual en:
http://code.google.com/p/ajcodekatas/source/browse/#svn/trunk/AjLanguage
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com