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.
Tabla de Contenidos
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.
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:
- Administrar eficientemente los recursos.
- Facilitar la interacción con el ordenador.
- Proporcionar un entorno para ejecutar las aplicaciones.
- 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:
| Papel | Qué hace | En tu portátil |
|---|---|---|
| Policía de tráfico | Organiza los recursos, maneja los conflictos cuando varios piden lo mismo y protege frente a errores y usos no deseados | Si una pestaña del navegador se cuelga, no se lleva por delante a VS Code |
| Facilitador | Reparte 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 errores | VS Code guarda un archivo sin saber qué disco tienes |
| Gobierno | Proporciona una parte de los recursos cuando hace falta y facilita interfaces estándar para compartirlos | Spotify 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.
| Quién | Qué entorno le da el SO | Qué aspecto tiene |
|---|---|---|
| Usuarios en general | Entorno de ejecución | GUI (interfaz gráfica: ventanas, iconos) o NUI (interfaz natural: voz, tacto, gestos) |
| Administradores | Entorno de administración | CLI o intérprete de comandos, el shell (bash, PowerShell) |
| Desarrolladores | Interfaz de programación | API 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:
fdes el descriptor de archivo: un número que identifica dónde vamos a escribir (un archivo abierto, la pantalla, un socket de red).bufferes un puntero a la zona de memoria donde están los datos.sizees 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:
| Beneficio | Qué significa | Ejemplo en tu portátil |
|---|---|---|
| Usabilidad | La interfaz es más cómoda que el hardware | Guardas con Ctrl+S, no moviendo el cabezal del disco |
| Seguridad | Se ocultan las vulnerabilidades del interior del hardware | Un programa no puede escribir donde le apetezca del disco |
| Portabilidad | El software no depende del hardware concreto | VS Code funciona igual con un SSD o con un disco mecánico |
| Interoperabilidad | Se comparte información con otros sistemas que usen la misma interfaz | Un pendrive formateado en tu portátil se lee en el de tu compañero |
| Mantenibilidad | Se puede mejorar el SO sin obligar a cambiar los programas de usuario | Una actualización del SO no te obliga a reinstalar Spotify |
| Productividad | La suma de todo lo anterior | Programas 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.
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:
- Optimizar el rendimiento del sistema.
- Justicia en el reparto: evitar que un proceso acapare los recursos y que otros sufran inanición (esperar para siempre).
- 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.
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.
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:
| Hito | Qué resuelve | En tu portátil |
|---|---|---|
| Multiprogramación | La CPU no se queda parada mientras un proceso espera su E/S | El compilador calcula mientras la descarga espera a la red |
| Paginación | Trocear un programa en páginas y colocarlas en huecos distintos de la memoria principal | VS Code no necesita un hueco libre enorme y seguido en la RAM |
| Memoria virtual | El programa no tiene que estar entero en memoria principal: el disco hace de extensión | Abres más programas de los que caben en tu RAM |
| Sistema de archivos | Guardar y encontrar datos y programas en memoria secundaria, organizados en archivos y directorios | Tu carpeta de apuntes de IC2 |
| Interfaz uniforme con la E/S | La misma API para cualquier dispositivo | write() vale igual para un pendrive que para un SSD |
| Control de acceso concurrente | Ordenar el acceso a un recurso que no pueden usar varios procesos a la vez | Dos programas que quieren la impresora: uno espera |
| Protección y seguridad | Que nadie pise ni lea lo que no es suyo | Tus 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: 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:
- 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:
| Sigla | Pregunta que responde | Significado |
|---|---|---|
| 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) | CPU | Esperando E/S | Qué pasa |
|---|---|---|---|
| 0-40 | C | — | El compilador calcula sus primeros 40 ms |
| 40-50 | D | C | C se va a su E/S; entra la descarga |
| 50-60 | M | C, D | D espera a la red 60 ms; entra Spotify |
| 60-100 | C | D, M | C ya terminó su E/S (40 + 20 = 60) y vuelve; acaba a los 100 ms |
| 100-110 | M | D | M terminó su espera a los 60 + 40 = 100 ms |
| 110-120 | D | M | D terminó su espera a los 50 + 60 = 110 ms |
Qué observar en la salida:
- La CPU ocupada no cambia (140 ms): la multiprogramación no hace que la CPU calcule menos ni más deprisa; elimina tiempo muerto.
- El tiempo total baja de 360 a 190 ms, y el uso de la CPU sube del 39 % al 74 %.
- 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.
- 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.
- 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
| Concepto | Lo que tienes que saber |
|---|---|
| Sistema operativo | Software que gestiona el hardware y da un entorno de ejecución a las aplicaciones; su núcleo está siempre en ejecución |
| Papeles | Policía de tráfico, facilitador y gobierno |
| SO como interfaz | Capa que envuelve al hardware: máquina extendida que oculta y añade; GUI, NUI, CLI (shell) y API |
| Llamadas al sistema | Servicios públicos del núcleo que se piden mediante la API (write(fd, buffer, size)) |
| Beneficios de la interfaz | Usabilidad, seguridad, portabilidad, interoperabilidad, mantenibilidad y productividad |
| SO como gestor | Recursos escasos, procesos que compiten: a qué proceso, cuánto, cuándo y cuánto tiempo |
| Criterios | Rendimiento, justicia y seguridad (confidencialidad, integridad, disponibilidad), en conflicto |
| Multiprogramación | Varios procesos en memoria; si uno espera E/S, la CPU ejecuta otro (concurrencia) |
| Hitos | Multiprogramación, paginación, memoria virtual, archivos, E/S uniforme, acceso concurrente, protección |
| Tipos | Lotes (JCL), tiempo compartido, tiempo real, multiusuario, SMP/AMP, UMA/NUMA, distribuidos, máquinas virtuales |
Tres ideas para llevarte:
- 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.
- Tu programa nunca toca el hardware: pide al núcleo con llamadas al sistema, y eso da usabilidad, seguridad y portabilidad.
- 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 →


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)