Programación Concurrente


Habitualmente  «programación» se asocia, primero con algoritmia y segundo, con un nicho determinado de aplicaciones. Éste último requiere típicamente el conocimiento de de un API (Interface de Programación de Aplicaciones) y probablemente herramientas adicionales; por ejemplo bases de datos, interfaces gráficos, tratamiento de imágenes, etc. Y finalmente se hallan el lenguaje de programación y herramientas de desarrollo que mejor se pueden adecuar al tipo de aplicaciones a desarrollar. Se podría establecer un paralelismo entre la programación y el lenguaje natural, y un API con un tópico particular.

Sin embargo, la Programación Concurrente no es una forma específica de programación ni atiende a determinadas necesidades de un ámbito de aplicaciones particular. Más bien se trata de un modelo de programación (con el soporte necesario, por supuesto)  transversal y complementario a lo que tradicionalmente se ha considerado la algoritmia o cualquier ámbito de aplicación determinado.

La programación concurrente consiste en desarrollar aplicaciones que consisten de varias “tareas” o “procesos” que “pueden” ser ejecutados en paralelo.  En caso de disponer de un único procesador, compartirán su uso intercalando sus ejecuciones; es un paralelismo simulado. Y en caso de disponer de varios procesadores o de tratarse de un sistema distribuido, el paralelismo será real.

Una aplicación inmediata de la programación concurrente es la multiplicación de la capacidad de computación. Sin embargo, incluso cuando esta capacidad de computación no es un cuello de botella, existen numerosos problemas que por naturaleza son concurrentes y resulta más sencillo resolverlos con un modelo de programación que lo refleje.

Por ejemplo, cuando un servidor en red está atendiendo a varios clientes simultáneamente, resulta útil diseñar dicho servidor atendiendo a un modelo que refleje tal concurrencia. En un sistemas de control donde además de ejecutar diversos algoritmos de control se han de atender a diversos periféricos de naturaleza diversa (UART, PWM, CAN, ADC, ..) también puede resultar útil emplear un modelo de programación que divida los diferentes cometidos en tareas concurrentes. Un navegador que debe descargar recursos para construir la página que ha de visualizar también podría beneficiarse de éste modelo de programación. Una hoja de cálculo puede consistir de varias tareas de las que una atiende al usuario, otra realiza cálculos en las celdas cuyos contenidos dependan del contenido de otras y otra tercera podría realizar copias de backup. Y un largo etc.

Los problemas a tener muy en cuenta en un modelo de programación concurrente provienen de la interacción de tareas. Es necesario “coordinar” el acceso a recursos que diversas tareas puedan estar compartiendo. O pueden aparecer problemas de “deadlock” en el que varios procesos se están esperando mutuamente sin que ninguno de ellos pueda avanzar. Y en el caso de aplicaciones de tiempo real es necesario asegurar que la competición de las diversas tareas por el procesador no impida que cada una de ellas pueda cumplir con el plazo asignado.

Y, ¿de qué soporte se puede disponer para desarrollar aplicaciones concurrentes? Actualmente, los sistemas operativos ya disponen de la capacidad de multiproceso. Adicionalmente, un proceso también puede consistir en varios hilos de ejecución; es lo que se denomina multithreading o multihilo. Para la coordinación entre hilos o tareas, existen numerosos mecanismos como semáforos, monitores, o mecanismos de paso de mensajes. Y para el caso de una programación distribuida se necesitará alguna infraestructura de comunicaciones.  Por citar algunos, JAVA y C# ya ofrecen algunos elementos a nivel de lenguaje y adicionalmente como librería estándar en su SDK. Bajo Linux, la librería pthread  ofrece mecanismos para la programación multihilo.

Todos estos elementos constituyen un soporte en forma de librerías y sistema operativo que permiten al programador desarrollar atendiendo a un paradigma de computación concurrente. No obstante,  no se debe olvidar que el desarrollador debe atender explícitamente a posibles problemas derivados de la interacción entre tareas, que como en cualquier desarrollo, exigirá una adecuada metodología de diseño.

+ No hay comentarios

Añade el tuyo