Programación concurrente en Linux

# Una perspectiva histórica de Linux y los sistemas operativos

## 1. Los sistemas operativos clásicos

Los sistemas operativos nacieron como una necesidad para manejar la ejecución de programas en los grandes, costosos y limitados computadores los primeros años de la informática. Los primeros sistemas operativos (década de 1950) propiamente dichos son los sistemas por lotes o batch, que permitían procesar en diferido paquetes de tarjetas perforadas basándose en el uso de un elemento software conocido en la época como monitor. Los usuarios no interaccionaban directamente con el computador, sino que entregaban los trabajos en un fajo de tarjetas perforadas (un lote) al operador del computador, quien ordenaba secuencialmente los lotes y los colocaba en un dispositivo de entrada (lector de tarjetas). Cada lote tenía insertadas tarjetas de control con órdenes para el monitor. La última tarjeta era una orden de retorno al monitor que le permitía comenzar a cargar automáticamente el siguiente programa.

Con el secuenciamiento por lotes, la unidad central de proceso (CPU) estaba a menudo sin trabajo debido a la lentitud de los dispositivos de entrada/salida (E/S) en comparación con la velocidad del procesador. Al ejecutar una instrucción de E/S, la CPU debía esperar ociosa a que el dispositivo concluyera la operación. Este tiempo de espera resultaba inadmisible en una época donde las CPUs tenían un precio desorbitadamente alto, lo que llevó a los ingenieros a idear estrategias para extraer el máximo rendimiento de la CPU. La idea era que, suponiendo memoria suficiente para varios programas, cuando un programa necesitara esperar por una E/S el sistema operativo cambiase la ejecución a otro programa que estuviera esperando CPU, permitiendo mantener el procesador ocupado. Esta técnica, conocida como multiprogramación o multitarea, se desarrolló a mediados en la década de 1960.

En aquella época se comenzaban a idear aplicaciones que exigían un modo de operación en el que el usuario, sentado ante un terminal, interaccionaba directamente con el computador. Este modo de trabajo es fundamental, por ejemplo, en el proceso de transacciones o consultas, y se denomina interactivo, en contraposición al batch. El procesamiento interactivo exige multiprogramación, pero además debe proporcionar un tiempo de respuesta (tiempo que transcurre desde que se lanza una transacción hasta que se obtiene la respuesta) razonablemente corto. Es decir, un usuario que interacciona desde un terminal no puede estar a expensas de que otro programa deje libre la CPU para entrar a ejecución. En un extremo, puede ocurrir que un programa muy orientado a cálculo ocupe la CPU indefinidamente. Por esta razón, en los sistemas introducidos en la segunda mitad de la década de 1960, el sistema operativo ejecuta los programas de forma intercalada, en quantums o ranuras de tiempo, expulsándolos del procesador cuando se cumple el quantum. A estos sistemas multiprogramados se les denomina de tiempo compartido. Un ejemplo notable es UNIX (1969). UNIX es un sistema innovador por varios motivos, entre ellos por romper con la tradición de los sistemas propietarios, en los que el fabricante proporciona el hardware, el sistema operativo y las aplicaciones. Al reescribirse casi completamente en C en 1973, UNIX es transportable a otras arquitecturas, y por lo tanto también lo son las aplicaciones a nivel de código fuente.

En esta época, la multiprogramación empieza también a utilizarse para la programación concurrente, necesaria en aplicaciones que deben atender eventos simultáneos, como las entradas de un sistema de control, que a veces requieren una respuesta en tiempo real.

Por su elevado coste, un computador primitivo se compartía por muchos usuarios, lo que enseguida condujo a la necesidad de identificar usuarios e incluir políticas de gestión de cuentas de usuario y de protección de accesos para proporcionar privacidad e integridad. En los primitivos sistemas basados en monitor, esta función la llevaba a cabo manualmente el operador del sistema, pero muy pronto los sistemas comienzan a ser multiusuario, en el sentido de que incluyen mecanismos automáticos para la gestión de usuarios.

## 2. Sistemas operativos para ordenadores personales

El abaratamiento del hardware con la irrupción del microprocesador a finales de la década de 1970, hizo posible proporcionar un sistema dedicado para un único usuario a un coste reducido, una característica fundamental en un sistema personal. En sus principios, los sistemas operativos para computadores personales, como MS-DOS (1981), son monousuario (carecen de mecanismos de protección) y monotarea; es decir, no muy diferentes de los primitivos sistemas de 30 años atrás, salvo por el hecho de usarse interactivamente mediante un terminal. Sin embargo, la vertiginosa evolución del hardware pronto permitiría que los ordenadores personales soportaran sistemas operativos multitarea y multiusuario (MacOS, Windows, Linux), además de interfaces gráficas de usuario sofisticadas.

En un computador personal la multiprogramación pierde el objetivo que motivó su desarrollo 30 años antes, ya que el microprocesador es muy barato. Sin embargo, las aplicaciones corrientes se hacen cada vez más concurrentes, requiriendo que varios flujos de ejecución progresen simultáneamente. Esto ocurre por ejemplo en un editor de texto, donde pueden diferenciarse tareas independientes para tratar la entrada, revisar la ortografía y guardar copias de seguridad. Esta concurrencia podría ser resuelta por la multiprogramación original, ya que esta permite coordinar el acceso a los recursos compartidos, ya sea una impresora o una variable en memoria con el texto editado. Sin embargo, los mecanismos de multiprogramación, basados en coordinar programas completos (procesos), no resultan demasiado eficientes para la concurrencia de grano fino que requieren las nuevas aplicaciones, por lo que pronto se introducen en los sistemas operativos nuevas interfaces para la programación multithread o multihilo, basadas en el uso de memoria compartida por los hilos (flujos de ejecución) de un proceso.

La llegada del computador personal tiene otro efecto. Hasta entonces, los sistemas multitarea de las grandes empresas (por ejemplo, un banco) podían ser accedidos remotamente (desde las sucursales del banco) a través de terminales “tontos”. El computador personal viene a sustituir a estos terminales, que se convierten ahora en sistemas autónomos que pueden asumir determinadas tareas (por ejemplo, edición de textos), descargando al sistema central. Además, pueden ejecutar de forma autónoma cualquier protocolo de comunicación. Una vez acordado un protocolo (por ejemplo, TCP/IP), los ordenadores personales pueden comunicarse entre ellos. Con el tiempo, el concepto de computador central tiende a desaparecer; ahora hay que hablar de conjunto de computadores que se conectan entre sí utilizando una infraestructura de red. Un computador de la red que proporciona y gestiona el acceso a un determinado recurso es el servidor de ese recurso, y los clientes solicitan al servidor el acceso al recurso (esquema cliente-servidor). La aparición y la amplia difusión de las redes de computadores ha complicado sobremanera no solo el sistema operativo sino también los servicios que se implementan sobre este, dando lugar a sistemas y aplicaciones de todo tipo en el ámbito de Internet y que han generado conceptos y esquemas de servicio muy elaborados, como los servicios web y la computación en la nube.

Linux (1991) es un miembro de la familia de sistemas UNIX orientado a ordenadores personales, aunque no limitado a estos. Linux es destacable por ser un producto de software libre, un fenómeno que revolucionó el mercado del software y en particular de los sistemas operativos. El software libre se caracteriza por no estar sujeto a las limitaciones de copia y distribución propias del software propietario. Internet constituye el medio necesario para la compartición y el intercambio ágil de ideas y código entre la comunidad de programadores que desarrollan software libre. Como consecuencia, y así se ha demostrado ampliamente, se dinamiza la adaptación del software y el desarrollo de nuevos productos, y se corrigen errores y afinan versiones con gran agilidad. Organizaciones como GNU otorgan licencia de copia, modificación y redistribución del software libre con la condición de que la nueva distribución incluya el código fuente (licencia Copyleft). Linux es con diferencia el sistema de la familia UNIX más utilizado en la actualidad. Además, fuera del ámbito de la informática personal, Linux es el sistema más extendido en el ámbito de los servidores y de los sistemas empotrados.

## 3. Sistemas para dispositivos móviles y empotrados

La evolución del hardware no acaba con los computadores personales. A lo largo de los años, estos se hacen cada vez más pequeños y eficientes, convirtiéndose en portátiles gracias a una batería que les permite funcionar sin conexión a la red eléctrica. A su vez, se desarrollaron las comunicaciones inalámbricas, lo que también contribuye a su movilidad.

Con el nuevo siglo, y de la mano de la evolución de la telefonía móvil, aparecen nuevos dispositivos con capacidad de cómputo creciente. Actualmente podemos encontrar en el mercado teléfonos inteligentes y tabletas capaces de soportar versiones reducidas de los sistemas operativos diseñados para computadores personales (MacOS, Windows, Linux), aunque también aparecen sistemas operativos específicos (como Android, basado en código del núcleo de Linux). Estos dispositivos móviles tienen prestaciones nada desdeñables e incluyen nuevas formas de E/S (pantallas táctiles, cámaras, posicionamiento…) que dan lugar a nuevos tipos de aplicaciones, como la navegación.

A medida que la tecnología informática ha ido copando ámbitos de aplicación, se han desarrollado tipos específicos de sistemas operativos. Los sistemas de tiempo real, presentes desde hace tiempo en la industria (sistemas de control), se generalizan y se extienden a otros ámbitos, como por ejemplo en sistemas de audio y video. Muchas veces estos sistemas están empotrados en sistemas más complejos, como un reproductor multimedia, un robot aspirador o un dron. En los sistemas de tiempo real la respuesta, además de correcta, tiene como requisito un plazo de tiempo antes del cual esta debe producirse. Cumplido el plazo, la respuesta carece de validez o incluso el incumplimiento puede resultar catastrófico (piénsese en el control de una aeronave o un automóvil). Se han desarrollado sistemas operativos para tiempo real específicos, como QNX, FreeRTOS y muchos otros. Los sistemas operativos de propósito general también soportan tareas de tiempo real, pero solo son adecuados en aplicaciones donde el incumplimiento del plazo no es crítico (por ejemplo, aplicaciones multimedia). De hecho, existen numerosos sistemas empotrados que han adoptado Linux o Android, como routers y televisores.

Hoy en día la evolución tecnológica sigue ampliando el ámbito de aplicación de los sistemas operativos: desde cámaras, relojes, pulseras y tarjetas inteligentes a dispositivos de control empotrados en electrodomésticos o automóviles, pasando por sistemas de monitorización y control del entorno (motas o sensores) y la robótica. Estos dispositivos son capaces de interaccionar entre ellos sin intervención humana. Se ha acuñado el término de sistemas ubicuos para referirse a este tipo de sistemas, y se suele hablar de inteligencia ambiental para denotar las aplicaciones que surgen en estos entornos.

Como resumen, hay que destacar la trayectoria cíclica que han seguido los sistemas operativos a lo largo de la historia para adaptarse a los nuevos soportes hardware. Así, la multiprogramación (multitarea), desarrollada para los grandes sistemas de tiempo compartido, no puede ser soportada por los primeros PCs basados en microprocesador quince años después. A medida que el hardware de los ordenadores personales fue ganando en prestaciones, sus sistemas operativos fueron integrando estas técnicas y hoy en día son de enorme complejidad. Más recientemente la miniaturización ha conducido a la aparición de dispositivos móviles de tamaño diminuto y prestaciones limitadas. La historia se repite: si los primeros sistemas operativos para teléfonos móviles eran extraordinariamente simples, las versiones actuales son multitarea. ¿Seguirán la misma evolución los relojes, las tarjetas inteligentes, y las motas?