Investigación Programación Concurrente

Investigación Programación Concurrente

Introducción a la Programación Concurrente

La programación concurrente es un paradigma de desarrollo de software en el que varias tareas se ejecutan simultáneamente, en lugar de hacerlo secuencialmente. Esto permite mejorar el rendimiento y la eficiencia en aplicaciones modernas, especialmente en sistemas con múltiples núcleos de procesamiento.

La concurrencia, en el contexto de la programación, es la capacidad de descomponer un programa en partes que pueden ejecutarse independientemente unas de otras. En esta línea, la programación concurrente es una técnica en la que dos o más procesos o hilos ( threads ) de un  software  se inician, se ejecutan de forma intercalada mediante el cambio de contexto y se completan en un período de tiempo superpuesto gestionando el acceso a recursos compartidos como, por ejemplo, en un solo núcleo de CPU.

Esto no significa que se ejecuten varios procesos en el mismo instante de tiempo, aunque por los resultados puede parecerlo.

…Tarea 1 proceso 3 – Tarea 2 proceso 1 – Tarea 1 proceso 2 – Tarea 1 proceso 1 -> Núcleo CPU

Las distintas tareas de cada proceso o de cada  hilo  (evento o circunstancia) que tiene que ejecutar el procesador las va ejecutando secuencialmente una detrás de otra y de manera intercalada, pero en instantes de tiempo tan pequeños que parece que los procesos se ejecutan de manera simultánea.

Generalmente, se confunde la programación concurrente con la programación en paralelo. En la programación en paralelo las tareas se ejecutan en distintos procesadores al mismo tiempo (paralelo).

…Tarea 4 proceso 1 – Tarea 3 proceso 1 – Tarea 2 proceso 1 – Tarea 1 proceso 1 -> Núcleo CPU 1

…Tarea 4 proceso 2 – Tarea 3 proceso 2 – Tarea 2 proceso 2 – Tarea 1 proceso 2 -> Núcleo CPU 2

…Tarea 4 proceso 4 – Tarea 3 proceso 3 – Tarea 2 proceso 3 – Tarea 1 proceso 3 -> Núcleo CPU 3

Los programas concurrentes son difíciles de escribir porque la gestión de procesos independientes requiere la coordinación de los recursos compartidos.

Definición y diferencias con la programación secuencial.

  • Programación secuencial: Las instrucciones se ejecutan una tras otra en un solo hilo de ejecución.
  • Programación concurrente: Varias tareas pueden ejecutarse al mismo tiempo, compartiendo recursos del sistema.

Importancia de la Concurrencia en Sistemas Modernos

La concurrencia es crucial en:

  • Sistemas operativos multitarea
  • Servidores web y bases de datos
  • Computación en la nube
  • Inteligencia artificial y procesamiento de grandes volúmenes de datos

Modelos de concurrencia

Existen diferentes modelos para manejar la concurrencia:

Hilos y procesos

  • Hilos (Threads): Ejecutan tareas concurrentemente dentro de un mismo proceso. Comparten memoria.
  • Procesos: Entidades independientes con su propio espacio de memoria.

Paso de Mensajes vs.Memoria Compartida

  • Paso de mensajes: Los hilos o procesos se comunican intercambiando datos a través de canales o colas.
  • Memoria compartida: Varias entidades acceden a la misma memoria, usando mecanismos de sincronización.

Modelo de actores

  • Cada entidad (actor) procesa mensajes y puede generar nuevos actores.
  • Modelo utilizado en lenguajes como Erlang y frameworks como Akka en Java/Scala.

Problemas Clásicos de la Concurrencia

Condiciones de Carrera

Ocurre cuando dos o más hilos acceden a una misma variable compartida sin sincronización, provocando resultados inconsistentes.

Interbloqueos

Se da cuando dos o más procesos esperan indefinidamente por un recurso bloqueado por otro.

Inanición y Espera Activa

  • Inanición: Un proceso no obtiene los recursos que necesita debido a la prioridad de otros procesos.
  • Espera activa: Un proceso sigue verificando una condición sin liberar CPU.

Mecanismos de sincronización

Mutex, semáforos y monitores

  • Mutex: Bloqueo exclusivo de recursos.
  • Semáforos: Contadores que controlan acceso concurrente.
  • Monitores: Permiten acceso seguro a recursos compartidos.

Barreras y variables de condición

  • Barreras: Sincronizan la ejecución de varios hilos.
  • Variables de condición: Permiten la suspensión de hilos hasta que se cumpla una condición.

Ejemplos

La concurrencia está en todas partes en la programación moderna:

  • Varios ordenadores conectados en red.
  • Múltiples aplicaciones ejecutándose en una computadora.
  • Múltiples procesadores en una computadora (múltiples núcleos de procesador en un solo chip).

De hecho, la concurrencia es esencial en la programación moderna:

  • Los sitios web deben manejar múltiples usuarios simultáneamente.
  • Las aplicaciones móviles deben realizar parte de su procesamiento en servidores  cloud .
  • Las interfaces gráficas de usuario casi siempre requieren un trabajo en segundo plano que no interrumpa al usuario.

Escribir programas concurrentes no es una tarea particularmente fácil, ya que tratar con construcciones como subprocesos y bloqueos, y evitar problemas como condiciones de carrera y puntos muertos puede ser bastante engorroso. Sin embargo, ser capaz de programar con concurrencia seguirá siendo importante en el futuro.

Las velocidades de reloj del procesador ya no aumentan pero, en cambio, disponemos de más núcleos en cada nueva generación de chips. Por eso, en el futuro, para que un cómputo se ejecute más rápido, tendremos que dividirlo en partes concurrentes.

Casos de uso y aplicaciones

  • Sistemas Operativos: Manejo de procesos e hilos.
  • Servidores Web: Manejo de múltiples solicitudes concurrentes.
  • Computación Paralela: Ejecución distribuida en clusters de servidores.
PREGUNTAS

1. ¿Qué es la programación concurrente y en qué se diferencia de la programación secuencial?

Respuesta:
La programación concurrente es un paradigma en el que varias tareas se ejecutan simultáneamente, compartiendo recursos del sistema. En cambio, la programación secuencial ejecuta una tarea a la vez en un solo flujo de control. La concurrencia permite mejorar la eficiencia y el rendimiento en sistemas modernos.

2. ¿Cuáles son los principales modelos de concurrencia y cómo funcionan?

Respuesta:
Los principales modelos de concurrencia son:

  • Hilos y procesos: Los hilos comparten memoria dentro de un proceso, mientras que los procesos son independientes.

  • Paso de mensajes: Los procesos/hilos intercambian datos a través de colas o canales.

  • Modelo de actores: Cada actor maneja su propio estado y se comunica mediante mensajes, como en Erlang o Akka en Java.

3. ¿Cuáles son los problemas más comunes en la programación concurrente?

Respuesta:
Algunos problemas frecuentes hijo:

  • Condiciones de carrera: Cuando dos o más hilos acceden a una variable compartida sin sincronización, generando resultados inesperados.

  • Interbloqueos (Deadlocks): Ocurre cuando dos o más procesos esperan indefinidamente por recursos bloqueados por otros.

  • Inanición: Un proceso de baja prioridad nunca obtiene recursos porque otros procesos de mayor prioridad los capacitan.

4. ¿Cómo se pueden evitar las condiciones de carrera en sistemas concurrentes?

Respuesta:
Se pueden evitar utilizando mecanismos de sincronización como:

  • Mutex: Garantiza el acceso exclusivo a un recurso compartido.

  • Semáforos: Permiten controlar el número de hilos que acceden a un recurso.

  • Monitores: Implementan bloqueo automático en objetos compartidos.

5. ¿Cómo funcionan los semáforos en la programación concurrente y en qué casos son útiles?

Respuesta:
Los semáforos son contadores que regulan el acceso concurrente a un recurso. Hay dos tipos principales:

  • Semáforo binario: Solo permite un acceso a la vez (similar a un mutex).

  • Semáforo de conteo: Permite múltiples accesos simultáneos.
    Se utilizan en situaciones donde varios hilos necesitan controlar el acceso a recursos compartidos, como en bases de datos o sistemas operativos.

6. ¿Qué ventajas y desventajas tiene la programación concurrente?

Respuesta:
Ventajas:

  • Aumenta el rendimiento en sistemas multinúcleo.

  • Permite responder mejor a múltiples tareas simultáneas (ej., servidores web).

  • Optimice el uso de los recursos del sistema.

Desventajas:

  • Mayor complejidad en el desarrollo y depuración.

  • Introducción de problemas como interbloqueos y condiciones de carrera.

  • Mayor consumo de memoria si no se maneja adecuadamente.

8. ¿Qué es el modelo de memoria en la programación concurrente y por qué es importante?

Respuesta:
El modelo de memoria define cómo los hilos interactúan con la memoria compartida. Es importante porque determina la visibilidad y el orden en que los cambios en una variable compartida son observados por otros hilos. Por ejemplo, en Java, la palabra clave volatilegarantiza que un valor sea leído directamente de la memoria principal en lugar de un caché de hilo.

9. ¿Cómo se pueden prevenir los interbloqueos (deadlocks) en programas concurrentes?

  • Ordenamiento de recursos: Asegurar que los recursos sean adquiridos en el mismo orden por todos los procesos.

  • Tiempo de espera: Establecer tiempos de espera máximos para evitar bloqueos indefinidos.

  • Evitar bloqueos mutuos: No permitir que dos procesos se esperen entre sí eternamente.

10. ¿Qué tendencias y aplicaciones modernas utilizan programación concurrente?

  • Sistemas operativos: Manejo de procesos e hilos en ejecución.

  • Servidores web y bases de datos: Manejo de múltiples solicitudes simultáneas.

  • Computación paralela: Procesamiento distribuido en la nube.

  • Juegos y simulaciones: Ejecución simultánea de IA, físicas y gráficos.

 

 

Comentarios

Entradas populares