Qué es un sistema operativo — teoría con tu portátil en una tarde de estudio, una llamada a write() y la CPU que nunca descansa (y los tres programas que no se ejecutaban a la vez)

Primera clase de sistemas operativos en IC2. El profesor proyecta una foto de un portátil con Spotify sonando, VS Code compilando la práctica y el navegador bajando un PDF, y pregunta: «Si este portátil tiene una CPU con un solo núcleo, ¿cuántos programas se están ejecutando a la vez?». Yo, muy seguro: «Tres, se ve en la foto». Respuesta: uno. En cada instante la CPU ejecuta las instrucciones de un único programa; los otros dos están esperando a la red, al disco o a la tarjeta de sonido, o esperando su turno. Lo que parece «a la vez» es un truco del sistema operativo, y es tan bueno que ni lo notamos.

Hoy empezamos la parte de sistemas operativos de la teoría de IC2. Después de tres temas de redes (el último fue Direccionamiento IP y subredes), toca entender qué es ese software que está debajo de todo lo que usas: qué es un sistema operativo, cómo hace de interfaz entre tus programas y el hardware, cómo reparte los recursos, cuáles fueron sus grandes inventos y qué tipos de sistemas hay. El ejemplo guía es tu portátil en una tarde de estudio, y al final lo simularemos con Python para medir cuánto trabaja la CPU. Cuando acabes, practica con los ejercicios tipo examen de este tema.

Qué es un sistema operativo

Empecemos por la definición que cae en el examen. Un sistema operativo (SO) es el software que gestiona el hardware de un ordenador y proporciona un entorno de ejecución para los programas de aplicación de los usuarios.

Fíjate en las dos mitades de la frase: hacia abajo, gestiona el hardware; hacia arriba, da un entorno a las aplicaciones. Las preguntas trampa suelen darle la vuelta («el software que gestiona las aplicaciones y da un entorno al hardware») o confundirlo con otra cosa (el hardware, un compilador, las aplicaciones que vienen instaladas).

No hay una definición aceptada por todo el mundo. Los apuntes recogen varias: un software que hace de intermediario entre los usuarios y aplicaciones y el hardware; un conjunto de programas que gestionan los recursos, optimizan su uso y resuelven conflictos; e incluso, medio en broma, «cualquier cosa que un fabricante te venda como sistema operativo». Todas dicen lo mismo desde ángulos distintos.

Dónde está: las capas de tu portátil

¿Dónde está exactamente ese software? Mira el dibujo de abajo: un sistema informático se puede ver como cuatro capas. Arriba estás tú (o cualquier usuario: personas, máquinas u otros ordenadores). Debajo, las aplicaciones: Spotify, VS Code, el navegador, que usan los recursos para resolver problemas del usuario. Después, el sistema operativo, que controla y coordina el uso del hardware entre las aplicaciones y los usuarios. Y abajo del todo, el hardware: CPU, memoria, disco, Wi-Fi, tarjeta de sonido.

Capas de un sistema informático Cuatro capas apiladas: usuarios, aplicaciones (Spotify, VS Code, navegador), sistema operativo (programas del sistema y núcleo) y hardware (CPU, memoria, disco, Wi-Fi, sonido). El sistema operativo controla y coordina el hardware. ¿Dónde está el sistema operativo en tu portátil? Usuarios Aplicaciones Sistema operativo Hardware Tú (o personas, máquinas y otros ordenadores) Spotify VS Code Navegador Programas del sistema: el shell, el explorador de archivos… Núcleo (kernel): el único programa siempre en ejecución CPU Memoria Disco Wi-Fi Sonido controla más abstracto ↑ · más cerca del hardware ↓
El SO está entre tus aplicaciones y el hardware; dentro, solo el núcleo está siempre en ejecución.

Dentro del propio SO hay dos piezas que conviene distinguir:

  • El núcleo (kernel): el único programa que se ejecuta en todo momento mientras el ordenador está encendido. Es el SO en sentido estricto.
  • Los programas del sistema: vienen con el sistema operativo pero no son parte del núcleo, como el shell o el explorador de archivos. Se abren y se cierran como cualquier programa.

Todo lo demás (lo que no está asociado al sistema) es una aplicación. Así que no: el navegador no forma parte del SO, aunque venga instalado de fábrica.

Para qué sirve: objetivos y papeles

Los apuntes le dan al SO cuatro objetivos:

  1. Administrar eficientemente los recursos.
  2. Facilitar la interacción con el ordenador.
  3. Proporcionar un entorno para ejecutar las aplicaciones.
  4. Facilitar la evolución del software y del hardware: si cambias tu disco por uno más rápido, tus programas siguen funcionando sin tocar una línea.

Y lo describen con tres papeles (roles), tres metáforas que en el examen salen para relacionar:

PapelQué haceEn tu portátil
Policía de tráficoOrganiza los recursos, maneja los conflictos cuando varios piden lo mismo y protege frente a errores y usos no deseadosSi una pestaña del navegador se cuelga, no se lleva por delante a VS Code
FacilitadorReparte lo que todos necesitan y ofrece una «máquina extendida» que oculta el hardware para que programar sea más sencillo, rápido y con menos erroresVS Code guarda un archivo sin saber qué disco tienes
GobiernoProporciona una parte de los recursos cuando hace falta y facilita interfaces estándar para compartirlosSpotify y el navegador comparten la Wi-Fi sin pelearse

Pensar que el SO hace el trabajo útil del usuario. El SO no realiza trabajo productivo para ti: no redacta tu documento ni compila tu práctica. Lo hacen las aplicaciones; el SO les reparte el hardware para que puedan hacerlo.

¿Dónde puedes encontrar un SO? Prácticamente en todas partes: en tu PC, en un móvil, en una tele, en un reloj inteligente, en una nevera conectada y en los ordenadores de un avión. Un Arduino sencillo, en cambio, normalmente ejecuta un único programa directamente sobre el hardware, sin SO.

El sistema operativo como interfaz

Primera forma de mirar al SO: como una capa que envuelve al hardware y ofrece por encima una máquina abstracta (o «máquina extendida») más cómoda que la real. Esa capa hace dos cosas a la vez:

  • Oculta detalles incómodos del hardware: tu programa no sabe en qué sector del disco cae cada byte ni cómo se habla con la tarjeta Wi-Fi.
  • Amplía características que el hardware no tiene: el disco solo sabe de bloques; el SO te ofrece archivos y carpetas. La CPU solo ejecuta instrucciones; el SO te ofrece procesos que parecen tener la máquina para ellos solos.

Decir que la capa envuelve al software o a las aplicaciones. La capa envuelve al hardware; las aplicaciones están encima y la usan.

Una interfaz para cada tipo de usuario

¿Para quién es esa interfaz? Depende de quién se siente delante. El dibujo lo resume: cambian el usuario y el aspecto, pero todas las interfaces acaban en el núcleo.

Interfaces del sistema operativo Tres columnas: los usuarios en general usan GUI y NUI (entorno de ejecución), los administradores la CLI o shell (entorno de administración) y los desarrolladores la API de llamadas al sistema (interfaz de programación). Todas llegan al núcleo del sistema operativo, que es el único que toca el hardware. Una interfaz para cada tipo de usuario Usuarios en general entorno de ejecución GUI NUI ventanas · voz · tacto Administradores entorno de administración CLI el shell: bash, PowerShell Desarrolladores interfaz de programación API llamadas al sistema Sistema operativo (núcleo) Hardware
Cambia quién la usa y su aspecto, pero todas las interfaces acaban en el núcleo.
QuiénQué entorno le da el SOQué aspecto tiene
Usuarios en generalEntorno de ejecuciónGUI (interfaz gráfica: ventanas, iconos) o NUI (interfaz natural: voz, tacto, gestos)
AdministradoresEntorno de administraciónCLI o intérprete de comandos, el shell (bash, PowerShell)
DesarrolladoresInterfaz de programaciónAPI del SO: las llamadas al sistema

Sobre el intérprete de comandos (CLI): en algunos sistemas se implementa dentro del núcleo y en otros como un programa del sistema. Puede tener distintas formas (los distintos shells), incorpora un lenguaje sencillo para darle órdenes al SO (cargar programas, trabajar con archivos…) y unas órdenes las lleva incorporadas mientras que para otras llama a otros programas. Si has seguido los temas de Linux, ya lo conoces: es lo que hay detrás del $ de tu terminal.

Las llamadas al sistema: cómo pide un programa algo al SO

La interfaz de los desarrolladores es la más importante para entender cómo funciona todo por dentro. El SO ofrece a los desarrolladores y a los procesos un conjunto de servicios públicos accesibles mediante una API: las llamadas al sistema (system calls). Normalmente no se usan directamente, sino a través de las bibliotecas del sistema (en C, la libc).

El ejemplo de los apuntes es write() de UNIX, que escribe un bloque de datos en un archivo o en un dispositivo de E/S. Este es su prototipo en C:

int write(int fd, void *buffer, size_t size);

Tres argumentos y un resultado. En el dibujo tienes cada parte señalada y, debajo, el camino que sigue la petición:

La llamada write() La línea n = write(fd, buffer, size) con cada parte señalada: n es el resultado (bytes escritos), fd el descriptor del archivo o dispositivo, buffer dónde están los datos en memoria y size cuántos bytes. Debajo, el camino: tu proceso en modo usuario, la biblioteca libc, el núcleo (llamada al sistema) y el disco. Anatomía de una llamada al sistema n = write( fd , buffer , size ); resultado: bytes escritos descriptor: qué archivo o dispositivo puntero: dónde están los datos longitud: cuántos bytes Tu proceso modo usuario Biblioteca libc Núcleo llamada al sistema Disco o pantalla, red…
Tu programa nunca toca el disco: pide el servicio al núcleo con una llamada al sistema.
  • fd es el descriptor de archivo: un número que identifica dónde vamos a escribir (un archivo abierto, la pantalla, un socket de red).
  • buffer es un puntero a la zona de memoria donde están los datos.
  • size es la longitud de los datos en bytes.
  • El resultado es el número de bytes escritos. Puede ser menor que size, y un programa serio lo comprueba.

Lo importante es el camino de abajo: tu proceso nunca toca el disco. Llama a la biblioteca, la biblioteca hace la llamada al sistema, el núcleo comprueba que el descriptor es válido y que tienes permiso, y el manejador del dispositivo escribe de verdad. Si quieres verlo con código real que se ejecuta, lo hicimos en Llamadas al sistema en C.

Si en una pregunta aparece «servicios públicos del SO que se ofrecen a los desarrolladores mediante las bibliotecas del sistema», están hablando de las llamadas al sistema.

¿Qué ganamos poniendo una interfaz en medio?

Meter una capa entre los programas y el hardware tiene un coste (una indirección más), así que tiene que compensar. Compensa, y por seis motivos que el examen pide relacionar:

BeneficioQué significaEjemplo en tu portátil
UsabilidadLa interfaz es más cómoda que el hardwareGuardas con Ctrl+S, no moviendo el cabezal del disco
SeguridadSe ocultan las vulnerabilidades del interior del hardwareUn programa no puede escribir donde le apetezca del disco
PortabilidadEl software no depende del hardware concretoVS Code funciona igual con un SSD o con un disco mecánico
InteroperabilidadSe comparte información con otros sistemas que usen la misma interfazUn pendrive formateado en tu portátil se lee en el de tu compañero
MantenibilidadSe puede mejorar el SO sin obligar a cambiar los programas de usuarioUna actualización del SO no te obliga a reinstalar Spotify
ProductividadLa suma de todo lo anteriorProgramas más rápido y con menos errores

El sistema operativo como gestor de recursos

Segunda forma de mirar al SO: como gestor de recursos. Para entenderla hacen falta dos palabras con definición de examen:

  • Proceso: un programa en ejecución. Es una entidad activa: va avanzando, instrucción a instrucción, y en cada momento tiene un estado.
  • Recurso: algo físico o virtual que un proceso necesita para ejecutarse (CPU, memoria, disco, red, un archivo). Es una entidad pasiva.

¿Y qué diferencia hay entre programa y proceso? El programa es una colección de instrucciones guardada en el disco (pasiva). El proceso es ese programa ejecutándose. Si abres VS Code dos veces, hay un programa y dos procesos. Los procesos tendrán un tema entero (el 6); aquí basta con la idea.

El SO como árbitro

Ahora el problema: los recursos son escasos y los procesos compiten por ellos. Tu portátil tiene una CPU, una cantidad fija de RAM y un disco, y en una tarde de estudio el compilador, la descarga y Spotify los quieren a la vez. Alguien tiene que decidir, y ese alguien es el SO, que actúa de árbitro o mediador y asigna los recursos de forma justa y eficiente.

El SO como gestor de recursos Tres procesos (compilador, descarga y Spotify) piden recursos al sistema operativo, que los reparte entre CPU, memoria, disco y red. La política de gestión responde a qué proceso, cuánto, cuándo y por cuánto tiempo, y debe cumplir rendimiento, justicia y seguridad (confidencialidad, integridad, disponibilidad), criterios que entran en conflicto. El SO como árbitro de los recursos C · compilador D · descarga M · Spotify Sistema operativo decide y reparte CPU Memoria Disco Red La política responde a cuatro preguntas ¿a qué proceso? ¿cuánto? ¿cuándo? ¿cuánto tiempo? …cumpliendo tres criterios que chocan entre sí Rendimiento aprovechar al máximo Justicia sin acaparar ni inanición Seguridad confidencialidad · integridad · disponibilidad ⇄
Los recursos son escasos y los procesos compiten por ellos: el SO decide, y no puede maximizarlo todo a la vez.

Leer deprisa y marcar «los procesos son escasos y los recursos compiten por ellos». Le da la vuelta a la frase. Lo escaso son los recursos; los que compiten son los procesos.

Las reglas con las que decide son las políticas de gestión de recursos, y responden a cuatro preguntas que ves en el dibujo: a qué proceso se le da el recurso, qué cantidad, en qué momento y por cuánto tiempo. Ojo: a qué proceso, no a qué usuario.

Esas políticas deben cumplir tres criterios:

  1. Optimizar el rendimiento del sistema.
  2. Justicia en el reparto: evitar que un proceso acapare los recursos y que otros sufran inanición (esperar para siempre).
  3. Garantizar la seguridad del sistema, con sus tres elementos, la CIA: confidencialidad (intimidad, privacidad), integridad (que la información no se corrompa) y disponibilidad (que el sistema siga dando servicio).

Y aquí viene lo interesante: estos criterios entran en conflicto. Si quieres el máximo rendimiento, dale toda la CPU al compilador y que acabe cuanto antes; pero entonces Spotify se queda sin turno y la música se corta, y eso no es justo. El SO siempre busca un equilibrio, nunca el máximo de todo.

Qué gestiona el SO

La lista de los apuntes, que en el examen sale como pregunta de respuesta múltiple:

  • Procesos: crearlos y borrarlos, suspenderlos y reanudarlos, y dar mecanismos de sincronización, comunicación y tratamiento de interbloqueos.
  • Memoria: saber qué partes están en uso y por quién, decidir qué procesos (o partes) entran y salen de memoria y asignar y liberar espacio.
  • Archivos: crear y borrar archivos y directorios, ofrecer una vista lógica y uniforme del almacenamiento y hacer copias de seguridad.
  • Dispositivos de almacenamiento masivo, caché y dispositivos de entrada/salida.
  • Protección y seguridad.

Los Temas 6 a 11 de esta serie son, uno a uno, estos gestores: procesos, planificación, concurrencia, memoria, memoria virtual y archivos.

La multiprogramación: el truco de la CPU que nunca descansa

Volvamos a la pregunta del principio. Un programa no usa la CPU todo el rato: alterna ráfagas de CPU (calcula) con esperas de E/S (espera a la red, al disco, a la tarjeta de sonido). La descarga del PDF, por ejemplo, calcula 10 ms y luego espera 60 ms a que lleguen datos de la red.

Sin multiprogramación, mientras un programa espera su E/S la CPU se queda parada: nadie más puede usarla hasta que ese programa termine del todo. Con multiprogramación (también llamada multitarea) hay varios procesos cargados en memoria y, cuando uno se bloquea esperando su E/S, la CPU ejecuta instrucciones de otro. La CPU y los dispositivos trabajan a la vez, y se terminan más trabajos en menos tiempo.

El dibujo enseña la tarde de tu portátil con los datos exactos del simulador del final del artículo: C es el compilador, D la descarga y M Spotify.

Multiprogramación con los datos del simulador Dos diagramas de tiempo con la CPU y la E/S de C (compilador), D (descarga) y M (Spotify). Uno detrás de otro: 360 ms y la CPU ocupada el 39 % del tiempo, con huecos mientras cada programa espera su E/S. Multiprogramada: 190 ms y un 74 %, porque mientras uno espera su E/S la CPU ejecuta a otro. La misma tarde, con y sin multiprogramación Uno detrás de otro · 360 ms CPU C C C C C C C C D D D M M M E/S de C E/S de D E/S de M 39 % Multiprogramada · 190 ms CPU C C C C D M C C C C M D M D E/S de C E/S de D E/S de M 74 % 0 40 80 120 160 200 240 280 320 360 ms CPU parada esperando su E/S
Mismo trabajo de CPU (140 ms): la multiprogramación rellena los huecos de E/S y la tarde dura casi la mitad.

Las dos filas de CPU hacen el mismo trabajo: 140 ms de CPU en total. Pero uno detrás de otro tardan 360 ms y la CPU está ocupada solo el 39 % del tiempo (140 / 360 = 0,39); multiprogramados tardan 190 ms y la CPU trabaja el 74 % (140 / 190 = 0,74). La multiprogramación no hace más rápida la CPU: rellena los huecos que dejan las esperas.

Decir que con multiprogramación, en una sola CPU, los procesos se ejecutan «en paralelo». En cada instante solo hay uno en la CPU. Los procesos entrelazan su ejecución: es concurrencia, no paralelismo. Paralelismo real solo hay con varios procesadores.

Lo que cambia en la memoria

Para poder saltar de un proceso a otro, los procesos tienen que estar cargados en memoria a la vez. Eso cambia el panorama, como ves en el dibujo: sin multiprogramación había el SO y un programa; con multiprogramación hay varios procesos, cada uno en su zona y con huecos libres entre medias.

Espacios de memoria privados A la izquierda, sin multiprogramación: el sistema operativo y un solo programa, con el resto libre. A la derecha, con multiprogramación: el sistema operativo, P1 Spotify, P2 VS Code y P3 navegador, cada uno en su zona con huecos libres. Una flecha roja de P2 hacia P1 está tachada: el sistema operativo impide que un proceso acceda a la memoria de otro. Memoria con y sin multiprogramación Sin multiprogramación SO VS Code (libre) Con multiprogramación SO P1 · Spotify P2 · VS Code (libre) P3 · navegador (libre)   el SO impide que un proceso toque la memoria de otro un programa cada vez: la memoria sobra y la CPU espera
Con varios procesos en memoria aparecen dos tareas nuevas para el SO: repartir el espacio y protegerlo.

El SO le da a cada proceso un espacio de memoria privado: ningún proceso puede acceder al espacio de otro (ni al del propio SO). Esa flecha roja tachada del dibujo es lo que pasaría si VS Code intentara escribir en la memoria de Spotify: el SO lo impide.

Problemas nuevos que trae

Tener varios procesos a la vez es un avance enorme, pero abre cuestiones que con un solo programa no existían:

  • Cuando la CPU queda libre, ¿a qué proceso se la damos? Es la planificación de la CPU (Tema 7).
  • Competencia por el consumo de la memoria: hay que repartirla (Temas 9 y 10).
  • Protección de las zonas privadas de memoria.
  • Conflictos cuando varios acceden a la vez al mismo recurso, y el riesgo de interbloqueo (deadlock): dos procesos esperándose el uno al otro para siempre (Tema 8).
  • Y de protección y seguridad: ¿cómo evitamos que un proceso dañe la memoria de otro o la del SO? ¿Cómo impedimos que acceda directamente a la E/S saltándose las políticas? ¿Cómo garantizamos que los datos privados de un usuario no los lee cualquier proceso? ¿Cómo nos aseguramos de que solo las personas autorizadas entran en el sistema?

Los hitos de los sistemas operativos

Algunas ideas de los SO cambiaron la informática para siempre. En el examen se preguntan como «logros históricos», y el truco es separar lo que inventó el SO de lo que inventaron el hardware o los lenguajes:

HitoQué resuelveEn tu portátil
MultiprogramaciónLa CPU no se queda parada mientras un proceso espera su E/SEl compilador calcula mientras la descarga espera a la red
PaginaciónTrocear un programa en páginas y colocarlas en huecos distintos de la memoria principalVS Code no necesita un hueco libre enorme y seguido en la RAM
Memoria virtualEl programa no tiene que estar entero en memoria principal: el disco hace de extensiónAbres más programas de los que caben en tu RAM
Sistema de archivosGuardar y encontrar datos y programas en memoria secundaria, organizados en archivos y directoriosTu carpeta de apuntes de IC2
Interfaz uniforme con la E/SLa misma API para cualquier dispositivowrite() vale igual para un pendrive que para un SSD
Control de acceso concurrenteOrdenar el acceso a un recurso que no pueden usar varios procesos a la vezDos programas que quieren la impresora: uno espera
Protección y seguridadQue nadie pise ni lea lo que no es suyoTus archivos no los lee el proceso de otro usuario

Marcar como hitos del SO los procesadores multinúcleo, los lenguajes de alto nivel o las pantallas táctiles. Son avances del hardware o de los lenguajes, no del sistema operativo.

Paginación frente a memoria virtual

Estas dos se confunden muchísimo porque la memoria virtual se apoya en la paginación. El dibujo las pone una al lado de la otra:

Paginación y memoria virtual A la izquierda, paginación: las cuatro páginas de VS Code se colocan en marcos de la memoria principal que no están juntos. A la derecha, memoria virtual: solo las páginas 0 y 1 están en memoria principal; la 2 y la 3 se quedan en el disco, que hace de extensión de la memoria. Paginación frente a memoria virtual Paginación VS Code página 0 página 1 página 2 página 3 memoria principal SO página 2 otro proceso página 0 página 3 página 1 trozos en huecos que no están juntos Memoria virtual VS Code página 0 página 1 página 2 página 3 memoria principal SO página 0 otro proceso libre página 1 otro proceso disco: páginas 2 y 3 no hace falta cargarlo entero
Paginación = trocear y repartir por la memoria principal; memoria virtual = no tener que cargarlo todo.
  • Paginación: el programa se trocea en páginas del mismo tamaño que se colocan en zonas diferentes de la memoria principal (que también está dividida en trozos de ese tamaño). Todo el programa está en la RAM, pero repartido.
  • Memoria virtual: el programa no necesita estar cargado entero en memoria principal; el almacenamiento secundario se usa como extensión de la memoria principal. En el dibujo, las páginas 2 y 3 se quedan en el disco hasta que hagan falta.

Las dos se resuelven automáticamente, sin que ni el usuario ni el programador tengan que intervenir. Lo verás a fondo en los Temas 9 y 10.

Si la opción habla de la memoria secundaria o de la caché al definir la paginación, es la trampa. La paginación solo habla de la memoria principal.

Interfaz uniforme con la E/S y control de acceso concurrente

La interfaz uniforme con la E/S consiste en ofrecer a los desarrolladores una API uniforme para acceder a cualquier dispositivo. Por dentro, cada dispositivo tiene su manejador (driver), que es transparente para el usuario final. Con eso se consigue la independencia del dispositivo: abstracción de los detalles de cada clase de periférico, portabilidad (el mismo código vale con dispositivos diferentes), adaptación a periféricos futuros y más seguridad, porque se puede prohibir el acceso directo a los dispositivos.

El control de acceso concurrente es el control del acceso a un recurso que no se puede compartir a la vez entre varios procesos. Dos procesos no pueden escribir a la vez en el mismo trozo de un archivo, ni imprimir mezclando sus páginas: el SO hace que uno espere. Es el germen del Tema 8.

Tipos de sistemas

La informática no es solo tu portátil. Los apuntes recogen muchos entornos de computación: ordenadores personales, dispositivos de mano (móviles y tabletas), sistemas empotrados (embedded), servidores y multiprocesadores, clústeres de servidores, supercomputadores, sistemas distribuidos, sistemas virtualizados y la nube. Y, según cómo se organizan, estos tipos de sistemas:

Por lotes, tiempo compartido y tiempo real

Tres formas de repartir el tiempo de CPU, con objetivos muy distintos. Compáralas en el dibujo:

Lotes, tiempo compartido y tiempo real Tres líneas de tiempo. Por lotes: trabajo 1, 2 y 3 seguidos sin intervención del usuario. Tiempo compartido: P1, P2 y P3 se turnan en rodajas de pocos milisegundos. Tiempo real: tres tareas (freno, ABS y airbag) que deben terminar antes de su plazo, marcado con una bandera roja. Tres formas de repartir el tiempo Por lotes años 50 · JCL trabajo 1 trabajo 2 trabajo 3 uno detrás de otro, sin que el usuario intervenga Tiempo compartido años 60 · interactivo P1 P2 P3 P1 P2 P3 P1 P2 P3 P1 P2 P3 rodajas de pocos ms: nadie nota las pausas Tiempo real control, multimedia freno ABS airbag cada tarea antes de su plazo (la bandera roja) tiempo
Lotes busca usar la CPU; tiempo compartido, que respondas rápido; tiempo real, que nada llegue tarde.
  • Procesamiento por lotes (batch): históricamente, los primeros SO (principios de los años 50). El objetivo era automatizar la ejecución de trabajos y aumentar el uso del procesador. Los trabajos se agrupaban en lotes y se ejecutaban en secuencia, sin control del usuario. Los más primitivos eran secuenciales; la multiprogramación se les incorporó a finales de los 60. Para dictarle tareas al SO nació el primer lenguaje de control, el JCL (Job Control Language).
  • Tiempo compartido (time sharing): inventados en los 50 y comercializados en los 60, buscaban interactividad. Cada proceso tiene una pequeña rodaja de tiempo periódica y los procesos se van turnando en la CPU. Si la rodaja es de unos pocos milisegundos, el usuario no percibe las pausas. Además, el mismo ordenador se puede compartir entre muchos usuarios.
  • Tiempo real (real time): diseñados para tareas que deben completarse en un plazo prefijado (control industrial, multimedia), con algoritmos de planificación especiales. En los críticos (industria, sistemas empotrados como el freno de un coche) incumplir un plazo es un fallo, y suelen prescindir de servicios que afectan a los tiempos, como la memoria virtual: traer una página del disco tarda un tiempo que no se puede garantizar.

Multiusuario no es multitarea

Un sistema multiusuario reconoce que hay varios perfiles de acceso con privilegios distintos: permisos sobre archivos y aplicaciones, cuotas de espacio o de tiempo de procesador, prioridad en el acceso a los recursos… Es lo que viste en Permisos en Linux.

Pensar que multiusuario y multitarea son lo mismo. Tu móvil es multitarea (varias apps a la vez) y lo usa una sola persona: puede haber sistemas multitarea que no son multiusuario.

Multiprocesadores

Los multiprocesadores van desde unos pocos hasta miles de procesadores. Se clasifican de dos maneras, y el dibujo pone las cuatro siglas juntas:

SMP, AMP, UMA y NUMA Cuatro paneles. SMP: cuatro CPU y cualquier tarea en cualquiera. AMP: la CPU0 ejecuta solo el sistema operativo y las otras los procesos de usuario. UMA: las cuatro CPU comparten una única memoria con el mismo tiempo de acceso. NUMA: cada CPU tiene su propia RAM; acceder a la de otra es más lento. Multiprocesadores: quién ejecuta qué y dónde está la memoria SMP · simétrico CPU0 CPU1 CPU2 CPU3 cualquier tarea, en cualquier CPU (también el propio SO) AMP · asimétrico CPU0 CPU1 CPU2 CPU3 solo el SO procesos de usuario cada CPU se especializa UMA · memoria compartida CPU0 CPU1 CPU2 CPU3 una memoria mismo tiempo de acceso para todas NUMA · memoria distribuida CPU0 RAM CPU1 RAM CPU2 RAM CPU3 RAM la propia, rápida; la de otra, más lenta
Arriba, cómo se reparten las tareas (SMP/AMP); abajo, cómo se accede a la memoria (UMA/NUMA).
SiglaPregunta que respondeSignificado
SMP¿Quién ejecuta qué?Multiprocesamiento simétrico: una tarea se puede ejecutar en cualquier procesador
AMP¿Quién ejecuta qué?Multiprocesamiento asimétrico: hay especialización (por ejemplo, un procesador ejecuta el SO y otros los procesos de usuario)
UMA¿Dónde está la memoria?Uniform Memory Access: memoria compartida, mismo tiempo de acceso para todos
NUMA¿Dónde está la memoria?Non Uniform Memory Access: memoria distribuida, cada procesador tiene la suya; la de otro es más lenta

Distribuidos y máquinas virtuales

Un sistema distribuido es un conjunto de ordenadores conectados en red que se usa como si fuera un único sistema con muchos procesadores, una gran memoria compartida y un gran almacenamiento. No existe un «sistema distribuido universal», pero sí servicios con características de sistema distribuido: los servicios en la nube (Dropbox, Amazon) o la propia web.

Una máquina virtual es la emulación por software de una máquina física: sobre ella se ejecutan programas hechos para la máquina emulada. Ventaja: no necesitas el sistema original. Inconveniente: la emulación es más lenta. Ejemplos históricos: IBM VM (años 60), que daba a cada usuario su propia máquina virtual, y VMware, capaz de ejecutar a la vez Windows, Linux y macOS. Sus usos:

  • Crear entornos protegidos: cada máquina virtual está aislada de las demás.
  • Independencia de la plataforma, como la máquina virtual de Java.
  • Pervivencia de sistemas antiguos: emuladores de MS-DOS o de consolas.
  • Desarrollo: escribir y probar aplicaciones para un hardware que no tienes.

Si seguiste la guía de Fedora en VirtualBox, ya has usado una.

Errores típicos del tema

Confundir el sistema operativo con las aplicaciones o con los programas del sistema. El SO en sentido estricto es el núcleo; los programas del sistema vienen con él; las aplicaciones no son parte del SO.

Confundir paginación (trocear en la memoria principal) con memoria virtual (no cargar el programa entero, usando el disco como extensión).

Escribir que la política decide «a qué usuario» se le dan los recursos. Decide a qué proceso, cuánto, cuándo y por cuánto tiempo.

Marcar «el SO realiza trabajo productivo para el usuario final». No lo hace: administra los recursos para que las aplicaciones lo hagan.

Para las preguntas de tipos de sistemas, asocia cada uno con su palabra clave: lotes → secuencial y desasistido (JCL); tiempo compartido → rodajas e interactividad; tiempo real → plazos; multiusuario → perfiles y privilegios; distribuido → muchos equipos que parecen uno.

Compruébalo con Python

Vamos a medir la multiprogramación en lugar de creérnosla. Este simulador reproduce la tarde de tu portátil: tres programas que alternan ráfagas de CPU y de E/S, primero uno detrás de otro y después multiprogramados. Cada letra de la línea de la CPU son 10 ms; un punto significa que la CPU está parada.

# Simulador de multiprogramación: ¿cuánto trabaja la CPU de tu portátil?
# Cada programa alterna ráfagas de CPU y de E/S (en ms). Datos fijos, sin input().
PROGRAMAS = {                     # nombre: [CPU, E/S, CPU, E/S, CPU]
    'C': [40, 20, 40],            # C = el compilador de VS Code (casi todo CPU)
    'D': [10, 60, 10, 60, 10],    # D = la descarga del PDF (espera a la red)
    'M': [10, 40, 10, 40, 10],    # M = Spotify (espera al disco y a la tarjeta de sonido)
}
PASO = 10                         # cada letra de la línea de la CPU son 10 ms


def simula(multi):
    queda = {p: list(r) for p, r in PROGRAMAS.items()}  # ráfagas pendientes
    listos, en_es, cpu, linea, fin = list(PROGRAMAS), [], None, '', {}
    while any(queda.values()):
        # sin multiprogramación nadie entra en la CPU mientras otro espera su E/S
        if cpu is None and listos and (multi or not en_es):
            cpu = listos.pop(0)
        linea += cpu or '.'                  # '.' = CPU parada
        for p in ([cpu] if cpu else []) + en_es:
            queda[p][0] -= PASO              # avanza la CPU y cada E/S (cada una en su dispositivo)
        for p in [p for p in en_es if queda[p][0] == 0]:
            queda[p].pop(0); en_es.remove(p)  # termina su E/S: vuelve a la cola de listos
            listos.insert(len(listos) if multi else 0, p)
        if cpu and queda[cpu][0] == 0:
            queda[cpu].pop(0)
            if queda[cpu]:
                en_es.append(cpu)            # se bloquea esperando la E/S y suelta la CPU
            else:
                fin[cpu] = len(linea) * PASO  # ha terminado del todo
            cpu = None
    return linea, fin


for multi in (False, True):
    linea, fin = simula(multi)
    ocupada, total = PASO * sum(c != '.' for c in linea), PASO * len(linea)
    print('Multiprogramada:' if multi else 'Uno detrás de otro:')
    print(f'  CPU |{linea}|')
    print('  terminan: ' + ', '.join(f'{p} a los {t} ms' for p, t in fin.items()))
    print(f'  total {total} ms, CPU ocupada {ocupada} ms, uso {100 * ocupada / total:.0f} %')

Las ráfagas siguen siempre el patrón CPU, E/S, CPU…, y suponemos que cada E/S va a su propio dispositivo (red, disco, tarjeta de sonido), así que varias esperas pueden avanzar a la vez. La CPU, en cambio, es una sola. Esta es la salida real de la única ejecución:

Uno detrás de otro:
  CPU |CCCC..CCCCD......D......DM....M....M|
  terminan: C a los 100 ms, D a los 250 ms, M a los 360 ms
  total 360 ms, CPU ocupada 140 ms, uso 39 %
Multiprogramada:
  CPU |CCCCDMCCCCMD...M..D|
  terminan: C a los 100 ms, M a los 160 ms, D a los 190 ms
  total 190 ms, CPU ocupada 140 ms, uso 74 %

Comprobemos las cuentas a mano. La CPU ocupada es la misma en los dos modos: C usa 40 + 40 = 80 ms, D usa 10 + 10 + 10 = 30 ms y M otros 30 ms, en total 80 + 30 + 30 = 140 ms. Uno detrás de otro, C tarda 40 + 20 + 40 = 100 ms, D tarda 10 + 60 + 10 + 60 + 10 = 150 ms y M 10 + 40 + 10 + 40 + 10 = 110 ms: 100 + 150 + 110 = 360 ms, y 140 / 360 = 0,39, el 39 %. Multiprogramados, 140 / 190 = 0,74, el 74 %.

La línea que decide si hay multiprogramación

Toda la diferencia entre los dos modos está en una condición:

# sin multiprogramación nadie entra en la CPU mientras otro espera su E/S
if cpu is None and listos and (multi or not en_es):
    cpu = listos.pop(0)

La CPU solo se le da a alguien si está libre (cpu is None) y hay alguien en la cola de listos. Con multi en True basta con eso. Sin multiprogramación se exige además not en_es: si algún proceso está esperando su E/S, nadie más puede entrar. Es justo lo que pasaba en los sistemas por lotes más primitivos: la CPU esperaba con el programa.

Qué pasa cuando termina una E/S

La otra pieza es dónde vuelve el proceso cuando termina su espera:

for p in [p for p in en_es if queda[p][0] == 0]:
    queda[p].pop(0); en_es.remove(p)  # termina su E/S: vuelve a la cola de listos
    listos.insert(len(listos) if multi else 0, p)

Con multiprogramación vuelve al final de la cola de listos (len(listos)), detrás de los que ya esperaban: un reparto justo por orden de llegada. Sin multiprogramación vuelve al principio (0), porque el programa que estaba en marcha tiene que terminar antes de que empiece el siguiente.

Esta es la traza de los primeros 120 ms del modo multiprogramado (cada fila es un tramo en el que no cambia nada):

Tramo (ms)CPUEsperando E/SQué pasa
0-40C—El compilador calcula sus primeros 40 ms
40-50DCC se va a su E/S; entra la descarga
50-60MC, DD espera a la red 60 ms; entra Spotify
60-100CD, MC ya terminó su E/S (40 + 20 = 60) y vuelve; acaba a los 100 ms
100-110MDM terminó su espera a los 60 + 40 = 100 ms
110-120DMD terminó su espera a los 50 + 60 = 110 ms

Qué observar en la salida:

  1. La CPU ocupada no cambia (140 ms): la multiprogramación no hace que la CPU calcule menos ni más deprisa; elimina tiempo muerto.
  2. El tiempo total baja de 360 a 190 ms, y el uso de la CPU sube del 39 % al 74 %.
  3. C termina a los 100 ms en los dos modos: aquí el compilador no sale perjudicado, porque cuando vuelve de su E/S la CPU está libre. Los que ganan son D y M, que ya no tienen que esperar a que C acabe del todo.
  4. Aún quedan puntos en la línea multiprogramada (de 120 a 150 ms y de 160 a 180 ms): cuando todos esperan su E/S, la CPU no tiene a quién ejecutar. Más procesos en memoria suelen tapar esos huecos… a cambio de más competencia por la memoria.
  5. Cambia los datos: pon 'C': [40, 20, 40, 20, 40] o una descarga con esperas más largas y mira cómo cambian el total y el porcentaje.

Resumen

ConceptoLo que tienes que saber
Sistema operativoSoftware que gestiona el hardware y da un entorno de ejecución a las aplicaciones; su núcleo está siempre en ejecución
PapelesPolicía de tráfico, facilitador y gobierno
SO como interfazCapa que envuelve al hardware: máquina extendida que oculta y añade; GUI, NUI, CLI (shell) y API
Llamadas al sistemaServicios públicos del núcleo que se piden mediante la API (write(fd, buffer, size))
Beneficios de la interfazUsabilidad, seguridad, portabilidad, interoperabilidad, mantenibilidad y productividad
SO como gestorRecursos escasos, procesos que compiten: a qué proceso, cuánto, cuándo y cuánto tiempo
CriteriosRendimiento, justicia y seguridad (confidencialidad, integridad, disponibilidad), en conflicto
MultiprogramaciónVarios procesos en memoria; si uno espera E/S, la CPU ejecuta otro (concurrencia)
HitosMultiprogramación, paginación, memoria virtual, archivos, E/S uniforme, acceso concurrente, protección
TiposLotes (JCL), tiempo compartido, tiempo real, multiusuario, SMP/AMP, UMA/NUMA, distribuidos, máquinas virtuales

Tres ideas para llevarte:

  1. El SO está en medio: gestiona el hardware por abajo y da servicio a las aplicaciones por arriba, y se mira de dos maneras, como interfaz y como gestor de recursos.
  2. Tu programa nunca toca el hardware: pide al núcleo con llamadas al sistema, y eso da usabilidad, seguridad y portabilidad.
  3. La multiprogramación aprovecha las esperas de E/S para que la CPU no descanse, y con ella nacen la planificación, la protección de la memoria y los problemas de concurrencia que veremos en los próximos temas.

Ahora toca demostrarlo: en los ejercicios tipo examen de Qué es un sistema operativo tienes un cuestionario interactivo con todos los formatos del examen, un cálculo de multiprogramación y preguntas de desarrollo. Y en el próximo tema bajamos un piso: el hardware que sostiene al sistema operativo (E/S, interrupciones, jerarquía de memorias y protección).

Siguiente paso: ejerciciosQué es un sistema operativo — ejercicios tipo examen con tu portátil, la multiprogramación medida en milisegundos y los tipos de sistemas (y la marca de más que me restó puntos)

¿Te ha servido este artículo? Así puedes apoyar SergioLearns →

Sigue aprendiendo

Deja una respuesta

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