¿Qué papel juega Oslo en la programación concurrente?

Hace un par de días estuve leyendo un interesante post del bueno de Rodrigo Corral acerca de los retos que la programación concurrente planteará en nuestros desarrollos en un futuro próximo, dada la emergente utilización de procesadores multinúcleo, y la necesaria búsqueda de eficiencia y productividad en nuestras aplicaciones. Uno de los comentarios que surgieron en dicho post se cuestionaba acerca de qué forma Oslo podría “casar” con este escenario, ya que chocarían por una parte la necesidad de acceder a las capas más bajas de abstracción de nuestra aplicación (para poder modificar ad-hoc el comportamiento concurrente de nuestro software en función de las características computacionales, es decir, el nº de CPUs, % de ocupación, etc., en cada escenario) con la abstracción que Oslo pretende conseguir, a fin de posibilitar una “programación más fácil”, basada en el uso de lenguajes específicos del dominio en que estemos moviéndonos en un problema concreto. Oslo nos permitirá definir estos lenguajes de forma sencilla, definir su gramática y dotarla de expresividad cercana incluso a la del lenguaje natural (digamos Español, Inglés, etc). Esta expresividad permitirá abrir el mundo de la programación a personas sin conocimientos previos en lenguajes de propósito general como C/C++, Java, C#, VB.Net… El propósito no es dejar sin trabajo a millones de programadores, ni mucho menos, sino conseguir que otros perfiles dentro de la empresa puedan modificar comportamientos concretos de nuestro software de forma intuitiva y sin necesidad de añadir tareas en la agenda ya de por sí apretada del programador. De esta forma estaremos consiguiendo una mayor agilidad en nuestros desarrollos, objetivo perseguido por las arquitecturas SOA.

Me pareció una pregunta bastante interesante y por ello voy a tratar de dar un primer diseño empleando Oslo, para afrontar el problema. Vaya por delante, no obstante, que el propósito no es desarrollar la solución completa sino más bien explicar las líneas de pensamiento que considero apropiadas en el diseño, y de qué forma las herramientas que componen Oslo me ayudarían a simplificar el proceso. Me gustaría recalcar en este punto el concepto de “líneas de pensamiento”, ya que hablar de Oslo implica necesariamente hablar de modelos, y un modelo es la representación abstracta de una realidad, o mejor dicho, de un modo concreto (el mío, ya que en este caso me pongo en la piel del arquitecto/diseñador del sistema) de entender dicha realidad.

Volviendo al contexto de la Programación Concurrente, cabe dar una definición concisa y correcta acerca del marco en que nos vamos a mover: (Extraído de Wikipedia)

“La computación concurrente es la simultaneidad en la ejecución de múltiples tareas interactivas. Estas tareas pueden ser un conjunto de procesos o hilos de ejecución creados por un único programa. Las tareas se pueden ejecutar en un sola unidad central de proceso (multiprogramación), en varios procesadores o en una red de computadores distribuidos.”

Felizmente, nada que los lectores de este post no sepáis ya. Así que obviaremos definiciones profundas y me limitaré a recalcar el concepto de Tarea, entendido como conjunto de instrucciones o acciones que precisan de una entrada (datos) y tras su procesamiento devuelven una salida (más datos). Si me lo permitís, a partir de ahora utilizaré indistintamente los términos Tarea y Agente (partiendo de asumir que una tarea o acción requiere de un actor o agente que la efectúe).

Además, tenemos dos mecanismos básicos para la sincronización de estas tareas en programación concurrente:

  1. Uso de segmentos de memoria compartida: A menudo diferentes tareas deben hacer uso de los mismos recursos (por extensión, de las mismas zonas de memoria, variables, estructuras…). Una forma de sincronizar estas tareas y también de garantizar el buen uso de estas zonas compartidas (de ahora en adelante “secciones críticas”) es regular el acceso de cada tarea a la sección crítica. De esta forma aseguramos que sólo una tarea accede a la sección crítica en un instante Ti, y que además el resto de tareas accederán a la sección crítica cuando la tarea anterior haya finalizado su interacción con la misma, y por supuesto el acceso será ordenado en base a un cierto criterio. Existen infinidad de formas (semáforos, monitores, etc.) de manejar estas políticas de asignación y prioridad (First Come First Served, Round-Robbin, etc.), por tanto recomiendo acudir a textos que se centren en Programación Concurrente para quienes quieran profundizar en esto.
  2. Intercambio de mensajes: Envío/recepción de mensajes entre diferentes Agentes. Estos mensajes constituyen una forma “educada”, de dar paso a la siguiente “persona” (agente) al baño (Sección Crítica), después de haberlo usado nosotros. Estos mensajes pueden ser de dos tipos:
    1. Bloqueantes: “Te espero hasta que salgas para volver a la barra”.
    2. No bloqueantes: “Me voy a seguir con lo mío, si necesitas algo ahora en salir me buscas otra vez”. 🙂

Por otra parte, es necesario recordar dos principios bastante frecuentes en el uso de datos extraídos de la memoria:

  1. Localidad temporal: Existe alta probabilidad de emplear un dato que acabamos de utilizar.
  2. Localidad espacial: Existe una alta probabilidad de que vayamos a necesitar un dato cercano en la memoria al dato que acabamos de utilizar.

Estos dos principios son muy habituales, no sólo en programación concurrente sino en otros dominios como puedan ser las aplicaciones web, las bases de datos, los conjuntos de variables…

Con todo esto, acabamos de llegar intuitivamente a una aproximación de la realidad bastante parecida al conocido Modelo de Actores, empleado desde el año 1973 en el mundo de la programación concurrente. Perfecto, 35 años después, Miguel acaba de reinventar la rueda.

Pero este capítulo de Barrio Sésamo que me he marcado en un momento no ha sido del todo involuntario, sino que he querido llevar nuestro razonamiento por una vía que nos ha conducido al punto perfecto para comenzar a hablar de Oslo en Programación Concurrente. Mirad qué dos palabras hemos empleado en los dos párrafos anteriores: “Dominios” y “Modelos“. Estas dos palabras son la A y la B de Oslo, la C sería la Capacidad para trabajar fácil e intuitivamente con ellos, para comunicarlos y compartirlos, para refinarlos y readaptarlos, y en definitiva, para que sean elementos centrales en nuestros desarrollos: Model-Driven Development.

Veamos qué forma tiene nuestro Modelo de actores:

image

Nos encontramos con un conjunto de tareas/actores/agentes independientes entre sí. Dichos agentes pueden ejecutar sus operaciones en un mismo procesador, en distintos procesadores de una misma máquina, o en distintos equipos. Lo que está claro es que dichos agentes van a necesitar comunicarse entre ellos, para ponerse de acuerdo (sincronizarse) y por tanto emplearán un canal para ello. Dicho canal dispondrá de un “acuerdo” entre emisor y receptor para definir las posibles acciones entre ellos. En un alarde de originalidad, bautizaré este concepto con el nombre de “Contrato”. Efectivamente, por segunda vez en este post, he reinventado la rueda.

Seguidamente vamos a modelar todo esto con el lenguaje de modelado de Oslo, el lenguaje M. Para ellos, abriremos Intellipad y declararemos una serie de entidades similares a las siguientes:

image

Como véis, la sintaxis del lenguaje M es bastante intuitiva. No me creo que alguno de vosotros tenga dudas sobre lo que hemos creado aquí. De todos modos, en futuros posts me centraré en particularidades del lenguaje, y también podéis acudir al MSDN Oslo Developer Center, donde encontraréis todo, todo y todo sobre Oslo, y por supuesto sobre M.

Sobre esta base, podemos aplicar muchas de las bondades de Oslo. Por ejemplo, podríamos crear una gramática con MGrammar (uno de los componentes del lenguaje M) que nos permitiera crear grafos PERT de tareas, como por ejemplo el siguiente.image

Gracias a MGrammar podríamos definir una gramática que permitiera a cualquier persona expresar dicho grafo con las siguientes palabras:

Crea T1. Crea T2. Crea T3.

Crea T4. Crea T5.

T2 depende de T1. T3 depende de T1.

T4 depende de T2 y T3.

T5 depende de T4.

A su vez, podríamos definir gramáticas más complejas que nos permitieran expresar en lenguaje natural las funciones a realizar por cada tarea. O también sentencias del tipo:

T1 ejecuta Suma de 3 y 4.

Donde “Suma de 3 y 4” podría traducirse por Sum(3, 4). O cualquier otra cosa que se nos ocurra.

Igualmente podríamos disponer de sentencias específicas de la programación concurrente, a la hora de definir dependencias. Por ejemplo:

T2 depende exclusivamente de T1.

T3 depende de T1 y T2. (de ambas)

T3 depende de T1 ó T2. (basta con que una tarea de ambas termine para que T3 pueda comenzar)

Todo esto sería fácilmente representable mediante el uso de MGrammar. No me detengo en expresarlo formalmente porque me pierdo la cena navideña, pero si el ejemplo os gusta, prometo avanzar en él.

Una vez generada la gramática, podríamos traducir dicho código a diferentes runtimes: ASP.Net, Dublín, WCF/WF… Es decir, podríamos traducir dichas dependencias y tareas a código CLR, o a cualquiera de los lenguajes de la familia .Net, e igualmente definir en dicha traducción cuantos comportamientos específicos del hardware queramos.

La labor de Oslo será dotar de mecanismos de alto nivel mediante el uso de gramáticas como la descrita anteriormente, lenguajes específicos de dominio textuales, y visuales (Quadrant). para que cualquiera pueda convertirse en desarrollador (a pesar de que ellos no lo sepan).

Por último, para quien en este punto se mantenga reticente al uso de lenguajes específicos de dominio en el ámbito de la programación concurrente, le recomiendo ver el siguiente vídeo publicado hace un par de días en Channel 9, acerca de MAESTRO, un proyecto de investigación orientado a la definición de lenguajes específicos de dominio para la programación concurrente en código .Net manejado.

Feliz Navidad!

 

 

 

6 comentarios en “¿Qué papel juega Oslo en la programación concurrente?”

  1. amigo excelente post y eso que todavía estamos en 2008, que nos explicarás en el 2009 !!! 😀

    con respecto a MAESTRO, me comi el video de C9 en el metro hace unos días y me gustó la idea, pero creo que la base de este post definirá los próximos años:

    “yo desarrollador a 10000 metros de altura, me gusta tener el control de TODO lo que pasa en mis applicaciones; me resulta un poco dificil dejar en manos de una nueva tecnología todo el detalle ‘delicado’ que es el hace la diferencia en una aplicación”

    a mi la idea me gusta (más con menos y mejor); a ver como evoluciona 😀

    Saludos

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *