Sistemas Operativos: Tres Piezas Fáciles. Parte 1: Introducción (traducción)

Introducción a los sistemas operativos

¡Hola, Habr! Quiero presentarles una serie de artículos traducidos de una literatura que considero interesante: OSTEP. Este material profundiza en el funcionamiento de los sistemas operativos similares a Unix, es decir, el manejo de procesos, diferentes planificadores, memoria y otros componentes similares que conforman un sistema operativo moderno. Pueden ver el original de todos los materiales aquí: aquí. Por favor, tengan en cuenta que la traducción se realizó de manera no profesional (bastante libre), pero espero haber mantenido el sentido general.

Los trabajos de laboratorio sobre este tema se pueden encontrar aquí:
— original: pages.cs.wisc.edu/~remzi/OSTEP/Homework/homework.html
— original: github.com/remzi-arpacidusseau/ostep-code
— mi adaptación personal: github.com/bykvaadm/OS/tree/master/ostep

Y también pueden visitar mi canal en Telegram =)

Funcionamiento del programa

¿Qué sucede cuando se ejecuta un programa? Un programa en ejecución realiza una tarea simple: ejecuta instrucciones. Cada segundo, millones e incluso posiblemente miles de millones de instrucciones son extraídas por el procesador de la memoria RAM, el cual las decodifica (por ejemplo, reconociendo a qué tipo pertenecen estas instrucciones) y las ejecuta. Esto puede incluir la suma de dos números, acceso a memoria, comprobación de condiciones, salto a funciones, entre otros. Al finalizar la ejecución de una instrucción, el procesador pasa a la siguiente. Así, instrucción por instrucción, se ejecutan hasta que el programa finaliza.
Este ejemplo, por supuesto, se ha presentado de forma simplificada; en realidad, para acelerar el trabajo del procesador, el hardware moderno permite ejecutar instrucciones fuera de orden, calcular resultados potenciales, ejecutar instrucciones simultáneamente y otros trucos similares.

Modelo de cálculo de von Neumann

La forma simplificada de trabajo que hemos descrito se asemeja al modelo de cálculo de von Neumann. Von Neumann fue uno de los pioneros de los sistemas informáticos, y también uno de los autores de la teoría de juegos.Durante la ejecución de un programa, ocurren muchas otras cosas, funcionan muchos otros procesos y lógicas externas, cuya principal objetivo es simplificar la ejecución, trabajo y mantenimiento del sistema.
Existe un conjunto de software responsable de facilitar la ejecución de programas (o incluso permitir ejecutar múltiples programas simultáneamente), permitiendo que los programas compartan la misma memoria y se interaccionen con diversos dispositivos. Este conjunto de software se conoce esencialmente como sistema operativo, y su tarea incluye asegurar que el sistema funcione correctamente y de manera eficiente, así como proporcionar facilidad en la gestión de este sistema.

Sistema operativo

El sistema operativo, abreviado como SO, es un conjunto de programas interrelacionados, destinado a gestionar los recursos del ordenador y organizar la interacción del usuario con el mismo..
El SO logra su eficiencia principalmente a través de la técnica más crucial: la técnica de virtualización. El SO interactúa con los recursos físicos (como el procesador, la memoria, el disco y similares) y los transforma en una forma más general, con mayores posibilidades y más sencilla de usar. Por lo tanto, para una comprensión general, se puede comparar de manera muy aproximada el sistema operativo con una máquina virtual.
Para permitir que los usuarios den comandos al sistema operativo y, de este modo, utilicen las capacidades de la máquina virtual (como: ejecutar programas, asignar memoria, acceder a archivos, etc.), el sistema operativo proporciona una interfaz llamada API (application programming interface) a la que se pueden realizar llamadas (call). Un sistema operativo típico permite realizar cientos de llamadas del sistema.
Y finalmente, dado que la virtualización permite que múltiples programas funcionen (compartiendo así el CPU), y accedan simultáneamente a sus instrucciones y datos (compartiendo memoria), así como acceder a discos (compartiendo dispositivos de entrada/salida), el sistema operativo también se conoce como gestor de recursos. Cada procesador, disco y memoria es un recurso del sistema y, por lo tanto, una de las funciones del sistema operativo es gestionar estos recursos de manera eficiente, justa o, por el contrario, dependiendo de la tarea para la que este sistema operativo fue diseñado.

Virtualización de CPU

Consideremos el siguiente programa:
(https://www.youtube.com/watch?v=zDwT5fUcki4&feature=youtu.be)

Sistemas Operativos: Tres Piezas Fáciles. Parte 1: Introducción (traducción)

No realiza acciones especiales; básicamente, lo que hace es llamar a la función spin(), cuya tarea es verificar cíclicamente el tiempo y devolverlo, después de que ha pasado un segundo. De esta manera, repite indefinidamente la cadena que el usuario ha pasado como argumento.
Ejecutemos este programa y le pasemos como argumento el símbolo “A”. El resultado no es especialmente interesante: el sistema simplemente ejecuta el programa que periódicamente muestra en pantalla el símbolo “A”.
Ahora intentemos una variante en la que se lanzan varias instancias del mismo programa, pero que muestran diferentes letras para que sea más claro. En este caso, el resultado será algo diferente. A pesar de que tenemos un solo procesador, el programa se ejecuta simultáneamente. ¿Cómo es posible? La respuesta es que el sistema operativo, con la ayuda de las capacidades del hardware, crea una ilusión. La ilusión de que hay varios procesadores virtuales en el sistema, convirtiendo un procesador físico en una cantidad teóricamente infinita y, por lo tanto, permitiendo que los programas parezcan ejecutarse simultáneamente. Esta ilusión se llama Virtualización de CPU.
Este tipo de escenario plantea muchas preguntas, por ejemplo, si varios programas desean ejecutarse simultáneamente, ¿cuál de ellos se ejecutará realmente? Esta cuestión es resuelta por las “políticas” del sistema operativo. Las políticas se utilizan en muchos lugares del sistema operativo y responden a preguntas como esta, además de ser mecanismos básicos que implementa el sistema operativo. De ahí la función del sistema operativo como gestor de recursos.

Virtualización de la memoria

Ahora examinemos la memoria. El modelo físico de la memoria en los sistemas modernos se presenta como un arreglo de bytes.Para leer desde la memoria, se debe indicar la dirección de la celda, para poder acceder a ella. Para escribir o actualizar datos, también es necesario indicar los datos y la dirección de la celda donde se escribirán.
Los accesos a la memoria ocurren constantemente durante la ejecución del programa. El programa mantiene en la memoria toda su estructura de datos y accede a ella al ejecutar diversas instrucciones. Las instrucciones también se almacenan en la memoria, por lo que los accesos a esta se producen también ante cada solicitud de la siguiente instrucción.

Llamada a malloc()

Consideremos el siguiente programa que asigna un área de memoria utilizando la llamada malloc() (https://youtu.be/jnlKRnoT1m0):

Sistemas Operativos: Tres Piezas Fáciles. Parte 1: Introducción (traducción)

El programa realiza varias tareas. En primer lugar, asigna cierta cantidad de memoria (línea 7), luego imprime la dirección de la celda de memoria asignada (línea 9), y escribe cero en la primera ranura de memoria asignada. A continuación, el programa entra en un bucle donde incrementa el valor almacenado en la memoria en la dirección de la variable “p”. También imprime su propio identificador de proceso. El identificador de proceso es único para cada proceso en ejecución.Si ejecutamos varias copias, nos encontraremos con un resultado interesante: en el primer caso, si no hacemos nada y simplemente ejecutamos varias copias, las direcciones serán diferentes. Pero eso no se ajusta a nuestra teoría. Correcto, ya que en las distribuciones modernas está habilitada por defecto la función de aleatorización de memoria. Si la desactivamos, obtendremos el resultado esperado: las direcciones de memoria de dos programas que se ejecutan simultáneamente coinciden.

Sistemas Operativos: Tres Piezas Fáciles. Parte 1: Introducción (traducción)

En consecuencia, resulta que dos programas independientes operan en sus propios espacios de direcciones privados, que a su vez son mapeados por el sistema operativo en la memoria física.Por lo tanto, el uso de direcciones de memoria dentro de un programa no afectará a los demás, y cada programa siente que tiene su propio trozo de memoria física, completamente a su disposición. La realidad, sin embargo, es que la memoria física es un recurso compartido, cuya gestión es responsabilidad del sistema operativo.

Consistencia

Otro tema importante en el ámbito de los sistemas operativos es consistencia. Este término se utiliza cuando se habla de problemas en el sistema que pueden surgir al trabajar con muchas cosas simultáneamente dentro de un mismo programa. Los problemas de consistencia también surgen en el propio sistema operativo. En los ejemplos anteriores sobre la virtualización de memoria y procesador, comprendimos que el sistema operativo gestiona muchas cosas al mismo tiempo: inicia el primer proceso, luego el segundo, y así sucesivamente. Resulta que este comportamiento puede dar lugar a ciertos problemas. Por ejemplo, los programas multihilo modernos enfrentan estas dificultades.

Consideremos el siguiente programa:

Sistemas Operativos: Tres Piezas Fáciles. Parte 1: Introducción (traducción)

El programa en la función principal crea dos hilos utilizando la llamada Pthread_create(). En este ejemplo, se puede pensar en un hilo como en una función que se ejecuta en un espacio de memoria junto a otras funciones, y el número de funciones ejecutándose simultáneamente es claramente más de una. En este ejemplo, cada hilo inicia y ejecuta la función worker(), que a su vez simplemente incrementa una variable.,.

Ejecutamos este programa con el argumento 1000. Como ya habrán adivinado, el resultado debería ser 2000, ya que cada hilo incrementó la variable 1000 veces. Sin embargo, no es tan simple. Intentemos ejecutar el programa con un número de repeticiones una orden de magnitud mayor.

Sistemas Operativos: Tres Piezas Fáciles. Parte 1: Introducción (traducción)

Al ingresar un número, por ejemplo, 100000, esperamos ver como salida el número 200000. Sin embargo, al ejecutar el número 100000 varias veces, no solo no obtendremos la respuesta correcta, sino que también obtendremos diferentes respuestas incorrectas. La clave está en que para aumentar el número se requieren tres operaciones: extraer el número de la memoria, incrementarlo y luego escribir el número de nuevo. Debido a que todas estas instrucciones no se realizan de manera atómica (todas al mismo tiempo), pueden ocurrir estas extrañas situaciones. Este problema se llama en programación condición de carrera.Cuando fuerzas desconocidas en un momento desconocido pueden influir en la ejecución de alguna de tus operaciones.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster