Recordamos que el sistema operativo es un “conjunto de programas” que se encarga de gestionar los recursos hardware y software del ordenador, por lo que actúa como una interfaz (intermediario) entre los programas de aplicación del usuario y el hardware.
Un proceso es un programa en ejecución. No debemos confundir programa con proceso. Cuando un programa se ejecuta, entonces pasa a ser un proceso. Un programa es un objeto pasivo, es decir un archivo de datos más en un medio de almacenamiento, sin embargo, un proceso es un objeto activo, al cual el sistema operativo asignará recursos que necesita para realizar su tarea (tiempo de CPU, memoria, archivos y dispositivos de e/s.) y controlará su ejecución.
No confundir programa con proceso
Cuando se crea un proceso, se le asocia un paquete de información denominado Bloque de Control de Proceso (BCP), que le acompaña durante toda su vida. En este BCP se recogen datos del proceso como son:
Todos los procesos, desde su creación, tendrán la capacidad de comunicarse y sincronizarse con otros procesos y con recursos del sistema. Este hecho da lugar a diferentes tipos de procesos:
En cualquier caso, la ejecución de los procesos exigirá concurrencia, cualidad que deberá gestionar el sistema operativo gracias a técnica denominada multiprogramación, que permite que dos o más procesos puedan ejecutarse simultáneamente.
De todos los procesos que se están ejecutando a la vez sólo uno tiene la “atención del usuario”; Este proceso se dice que está en primer plano y del resto se dice que están en segundo plano. Es posible pasar un proceso de primer plano a segundo plano y viceversa. Un demonio o daemon (Linux) o servicio o service (Windows) es un proceso que se ejecuta en segundo plano sin necesidad alguna de interacción con el usuario para llevar a cabo su tarea.
Los hilos o hebras (del inglés thread) representan un método software para mejorar el rendimiento y eficacia de los sistemas operativos. Los hilos de un mismo proceso compartirán recursos, como memoria, archivos, recursos hardware, etc.
En los actuales sistemas operativos, un proceso puede tener internamente varias actividades concurrentes llamadas hilos de ejecución. Son como “miniprocesos”, unidades pequeñas en las que se divide un proceso, cada una de las cuales realiza una acción.
Dicho de otra forma, cada hilo de procesamiento contiene un trozo de la tarea a realizar. De esta forma la CPU es capaz de procesar varias tareas al mismo tiempo y de forma simultánea, de hecho, podrá hacer tantas tareas como hilos tenga, y normalmente dos por cada núcleo.
Los sistemas operativos modernos están preparados para crear más de un hilo de ejecución en un proceso. Con las tecnologías multi-core (multiprocesador) esto se hace algo necesario para poder sacar mayor provecho al recurso de procesamiento. En los procesadores que tienen, por ejemplo 6 núcleos y 12 hilos, serán capaces de dividir los procesos en 12 tareas distintas, en lugar de solamente 6.
Los programas están desarrollados mediante un determinado lenguaje de programación.
Un programa está compuesto por unas determinadas lineas de código, las lineas de código describen operaciones específicas u ordenes que son las secuencias de instrucciones.
Para que un proceso se ejecute, su secuencia de instrucciones debe encontrarse en la memoria principal. Además, en todos los sistemas operativos modernos, se va intercalando la ejecución de distintos procesos, de forma que se alternan el uso del procesador.
Para saber en qué posición de memoria se encuentra la siguiente instrucción que debe ejecutarse, el procesador dispone de un registro llamado Contador de programa (en inglés, Program Counter, o PC), que irá cambiando de valor según pase el tiempo.
La secuencia de valores que vaya teniendo el Contador de programa podrán apuntar a instrucciones de diferentes procesos.
El procesador ejecutará el código perteneciente a un módulo del sistema operativo, llamado Distribuidor (en inglés, Dispatcher), cada vez que un proceso haya consumido su tiempo (medido en ciclos de instrucción) o haya solicitado algún servicio por el que deba esperar (p. ej. una operación de E/S).
Podemos definir un ciclo de instrucción como el tiempo que emplea el procesador en ejecutar una instrucción en lenguaje máquina y, de un modo simplificado, podríamos dividirlo en dos pasos:
Por este motivo, también suele llamarse ciclo de fetch-and-execute o fetch-decode-execute.
El procesador ejecutará el código perteneciente al distribuidor cada vez que un proceso haya consumido su tiempo o haya solicitado algún servicio por el que deba esperar. Así se evita que un proceso se apropie del procesador de forma indefinida. De esta forma se definen 5 estados:
Una de las claves para que un sistema multiprogramado sea eficaz es la Planificación de procesos, que consiste en ir asignando procesos al procesador (o procesadores / núcleos) a lo largo del tiempo, de forma que se cumplan los objetivos en varios aspectos:
El módulo del sistema operativo que se encarga de esta tarea se denomina Planificador (en inglés, Scheduler). Según el diseño del sistema operativo, el Planificador utilizará unos criterios u otros para llevar a cabo su tarea. Estos criterios reciben el nombre de Algoritmos de Planificación (o también, Políticas de Planificación). Se puede distinguir entre
Algunos de los algoritmos o políticas de planificación más importantes son:
En muchas ocasiones, un sistema operativo ejecuta varios procesos que deben comunicarse entre ellos para colaborar en un objetivo común. Para lograrlo, el sistema puede ofrecer una serie de funciones llamadas IPC (del inglés, Inter-Process Communication) que facilitan el envío de mensajes entre los procesos para comunicarse y sincronizarse.
Otra forma que tienen los procesos de comunicarse entre sí es compartiendo determinadas zonas de memoria.
Cuando los procesos que necesitan comunicarse están en ordenadores diferentes, se utiliza RPC (del inglés, Remote Procedure Call). Sin embargo, quien programa dichos procesos no tendrá que preocuparse de su ubicación física y de los aspectos que deriven de esa circunstancia. Para ellos, no habrá diferencia con la comunicación con procedimientos locales. Es decir, será el sistema operativo quien se encargue de resolver los problemas que se deriven de esta situación.
En los sistemas operativos de tiempo compartido, se pueden presentar problemas a la hora de competir por los recursos del sistema. El sistema operativo debe ofrecer mecanismos para sincronizar la ejecución de los procesos.
En la siguiente imagen vemos un proceso que se encuentra actualmente en ejecución (verde), otro que se encuentra bloqueado (amarillo) en espera de poder utilizar la impresora y un tercero (rojo) que se encuentra suspendido (no está usando la memoria principal, aunque la tiene solicitada)
Es importante que el sistema operativo trate de evitar el interbloqueo o bloqueo mutuo (en inglés, deadlock), que consiste en que dos procesos diferentes necesitan los dos mismos recursos y cada uno de ellos tiene uno asignado. Ambos estarán bloqueados en espera de que se libere el recurso que aún no tienen y, por lo tanto, ninguno liberará el recurso que ya poseen.
La memoria es un elemento clave del sistema operativo a la hora de ejecutar un proceso, ya que para que un proceso se ejecute es necesario que esté cargado en la memoria principal. La memoria principal es un recurso finito, por tanto el sistema operativo tiene que gestionarla eficientemente, la parte del sistema operativo destinado a administrar la memoria es el gestor de memoria.
El gestor o administrador de memoria se encarga de:
Para ejecutar una instrucción, hay que leerla desde la memoria a un registro del procesador y decodificarla A continuación, es posible que el sistema deba volver a la memoria para obtener los datos implicados en la operación. Finalmente, es común que los resultados obtenidos también haya que guardarlos en la memoria. Por todo ello, si la gestión de la memoria no es adecuada, el rendimiento general del sistema se verá inmediatamente disminuido.
En los primeros ordenadores, la memoria principal se dividía en dos partes: una para el Sistema Operativo que debía estar siempre en memoria (que recibía el nombre de monitor) y otra para un único proceso de usuario. Un ejemplo de este esquema lo representan las primeras versiones del sistema operativo MS-DOS.
Actualmente la mayoría de los sistemas operativos son sistemas multitarea, en los que va a haber varios procesos simultáneamente en ejecución. Para que esto sea posible, todos estos procesos deberán estar también simultáneamente en memoria, pues ésta es una condición necesaria para que un proceso pueda ejecutarse. Por tanto, deberá haber mecanismos de gestión para distribuir la memoria principal entre todos estos procesos que quieren ejecutarse. La asignación de memoria para distintos procesos ejecutándose concurrentemente suele hacerse, dependiendo del sistema operativo, de alguna de las siguientes formas:
La memoria se divide en un cierto número de particiones o zonas, cada una de las cuales contendrá un proceso. El tamaño de cada una de las particiones es determinado por un operador humano o por el sistema operativo, el tamaño de cada una de las particiones puede ser diferente.
¿Qué ocurre si el proceso a ejecutar ocupa menos espacio del asignado a la partición de memoria?
Si esto ocurre se da el fenómeno indeseado de la Fragmentación interna, supone que el espacio de memoria no se puede aprovechar al 100%
Consiste en particiones de memoria de tamaño variable, es decir, a cada proceso se le asigna la cantidad de memoria que necesita. Se deben utilizar algunos algoritmos para la ubicación de procesos en las particiones.
Cuando llega un proceso, se busca un bloque de memoria suficientemente grande para contenerlo y se le asigna sólo la porción necesaria. El resto del bloque queda libre para otra asignación. Cuando un proceso termina, la memoria que ocupaba queda disponible y, si se encuentra junto a otro bloque libre, se une a él.
En cualquier caso, el problema de esta idea es que, si hay múltiples asignaciones y liberaciones de memoria, ésta tenderá a tener una gran fragmentación externa que ocurre cuando una partición disponible no se emplea porque es muy pequeña para cualquiera de los procesos que esperan.
La fragmentación externa se resuelve aplicando, cuando sea necesario, un procedimiento de compactación de memoria, que consiste en desplazar los bloques asignados hacia un extremo y uniendo a su vez todos los bloques libres en uno más grande.
En este caso, el programa o proceso se divide en bloques llamados segmentos.
La gestión la realiza el SO, como las particiones dinámicas, sólo que cada partición no corresponde a un proceso sino a un segmento. El sistema operativo mantiene una tabla-mapa de segmentos, indicando la ubicación en memoria de cada uno de ellos y su tamaño.
La paginación es una técnica que consiste en dividir la memoria principal en zonas iguales llamadas marcos de longitud fija.
Los programas se dividen en bloques del mismo tamaño de los marcos denominadas páginas. Debemos tener en cuenta que un proceso no tiene porqué ocupar toda una página. Es decir, en la división del proceso en páginas, es posible que la última página tenga menor tamaño que las anteriores, por lo que puede producirse fragmentación interna
Las páginas se almacenan en marcos de página independientemente de que estén o no contiguos. De este modo, cuando llegue un nuevo proceso, el único problema será encontrar la cantidad suficiente de marcos de página disponibles en la memoria principal.
Este esquema necesita un método que traduzca las direcciones virtuales a direcciones físicas, teniendo en cuenta la ubicación real de cada marco de página. Este método se basa en la creación de una tabla de páginas, para cada proceso, en el momento de cargarlo en memoria. En ella se establecerá el paralelismo entre cada página y su marco de página correspondiente.
Gracias a este planteamiento, se acaba con la fragmentación externa, y la fragmentación interna quedará reducida al último marco de página asignado a cada proceso.
Hay ocasiones que no se dispone de suficiente memoria real o principal para cargar un proceso ya que el tamaño de proceso es mayor que la memoria disponible. Para solucionar estos casos surge la memoria virtual.
Normalmente se implementa a partir de los conceptos de paginación y/o segmentación.
La memoria virtual utiliza el espacio libre de las unidades de almacenamiento como si fuesen parte de la memoria RAM. Si se necesita ejecutar una parte del programa que está almacenada en memoria virtual, esta pasará a RAM para su ejecución real y la parte del programa que estaba en RAM pasará a disco. Así siempre se tiene más RAM liberada para realizar cálculos o ejecutar otros programas
Una de las funciones principales de un sistema operativo es el control de los periféricos de entrada/salida del ordenador. El sistema operativo se encarga de enviar órdenes, determinar el dispositivo que necesita la atención del procesador, eliminar posibles errores, etc.
El concepto de archivo posibilita aislar al usuario de los problemas físicos de almacenamiento ya que auqnue en un sistema informático, aunque la memoria principal es indispensable para ejecutar procesos, no es un medio válido para el almacenamiento de los programas y los datos a largo plazo por dos motivos fundamentales:
Para solventar estas carencias, se utilizan los dispositivos de memoria secundaria, como Discos duros, Unidades SSD, Unidades USB, discos ópticos, etc.
El Sistema de archivos (en inglés, filesystem) es el componente del sistema operativo que se encarga de organizar el modo en el que se guardan los datos dentro de los dispositivos de almacenamiento secundario. Para llevar a cabo su tarea, desde un punto de vista lógico utiliza dos conceptos diferentes:
Archivo (o fichero): es una serie de bytes almacenados en un dispositivo de almacenamiento externo que, en conjunto, forman una unidad lógica. Cada archivo suele estar identificado en el sistema mediante un nombre y una extensión. Normalmente, el nombre sirve para identificar el contenido del archivo y la extensión para identificar el tipo al que pertenece (si es un documento, una imagen, etc.). Para evitar ambigüedades, no pueden existir dos archivos que tengan el mismo nombre y extensión dentro de la misma ubicación.
Carpeta (o directorio): es un modo de agrupar archivos, según el criterio del usuario, para facilitar su organización. Igual que los archivos, las carpetas tienen un nombre que las identifica. Para un sistema de archivos, una carpeta no es más que un archivo que contiene información sobre el modo en el que se organizan los datos. Como en el caso de los archivos, para evitar ambigüedades, no puede haber dos carpetas con el mismo nombre en la misma ubicación.
Como podemos suponer, la unidad de información con la que trabaja un sistema de archivos es, precisamente, el archivo.
Es frecuente que cada familia de sistemas operativos tenga sus propios sistemas de archivos. Por ejemplo, a continuación relacionamos los más conocidos:
A pesar de todo, como podemos ver en la tabla anterior, existe cierto nivel de compatibilidad entre los diferentes sistemas operativos en cuanto a los sistemas de archivos, bien directamente (los incluidos en la tabla), bien a través de herramientas complementarias.
Por lo tanto, un sistema de archivos se encargará de aspectos como: