Vous êtes sur la page 1sur 5

Luis Miguel Ovalle Clase (2012-1923)

Resumen del capítulo 2 y 3


La memoria más rápida de la computadora son los registros, ubicados en cada uno de
los núcleos de cada CPU. Las arquitecturas tipo RISC (Reduced Instruction Set
Computer) sólo permiten la ejecución de instrucciones entre registros (excepto, claro,
las de carga y almacenamiento a memoria primaria). Los primeros CPU trabajaban con
pocos registros, muchos de ellos de propósito específico, se regían más bien con una
lógica de registro acumulador. Por ejemplo, el MOS 6502 (en el cual se basaron las
principales computadoras de ocho bits) tenía un acumulador de ocho bits (A), dos
registros índices de ocho bits (X e Y), un registro de estado del procesador de ocho bits
(P), un apuntador al stack de ocho bits (S), y un apuntador al programa de 16 bits (PC).
En contraposición con proceso, en un sistema por lotes se habla de tareas, una tarea
requiere mucha menos estructura, típicamente basta con guardar la información
relacionada con la contabilidad de los recursos empleados. Una tarea no es interrumpida
en el transcurso de su ejecución. Ahora bien, esta distinción no es completamente
objetiva y se pueden encontrar muchos textos que emplean indistintamente una u otra
nomenclatura. Si bien el sistema brinda la ilusión de que muchos procesos se están
ejecutando al mismo tiempo, la mayor parte de ellos típicamente está esperando para
continuar su ejecución en un momento determinado sólo puede estar ejecutando sus
instrucciones un número de procesos igual o menor al número de procesadores que
tenga el sistema.
Todos los sistemas de cómputo están compuestos por al menos una unidad de proceso
junto con dispositivos que permiten ingresar datos (teclado, mouse, micrófono, etc.) y
otros que permiten obtener resultados (pantalla, impresora, parlantes, etc.). Como se vio
anteriormente, una de las funciones del sistema operativo es la de abstraer el hardware
de la computadora y presentar al usuario una versión unificada y simplificada de los
dispositivos. En este capítulo se verá la relación que mantiene el sistema operativo con
el hardware, las funciones que cumplen y algunas abstracciones comunes utilizadas en
sistemas operativos modernos.
memoria de la siguiente instrucción a ejecutar. La arquitectura von Neumann fue
planteada, obviamente, sin considerar la posterior diferencia entre la velocidad que
adquiriría el CPU y la memoria. En 1977, John Backus presentó al recibir el premio
Turing un artículo describiendo el cuello de botella de von Neumann. Los procesadores
son cada vez más rápidos (se logró un aumento de 1 000 veces tanto entre 1975 y 2000
tan sólo en el reloj del sistema), pero la memoria aumentó su velocidad a un ritmo
mucho menor; aproximadamente un factor de 50 para la tecnología en un nivel costo-
beneficio suficiente para usarse como memoria primaria. Una respuesta parcial a este
problema es la creación de una jerarquía de almacenamiento, yendo de una pequeña
área de memoria mucho más cara pero extremadamente rápida y hasta un gran espacio
de memoria muy económica, aunque mucho más lenta, como lo ilustran la figura 2.1 y
el cuadro 2.1. En particular, la relación entre las capas superiores está administrada por
hardware especializado de modo que su existencia resulta transparente al programador.
Ahora bien, aunque la relación entre estos medios de almacenamiento puede parecer
natural, para una computadora tiene una realidad completamente distinta: los registros
son parte integral del procesador, y la memoria está a sólo un paso de distancia (el
procesador puede referirse a ella directamente, de forma transparente, indicando la
dirección desde un programa). Para efectos prácticos, el caché no se maneja
explícitamente: el procesador no hace referencia directa a él, sino que es manejado por
los controladores de acceso a memoria.
El compilador2 busca realizar muchas operaciones que deben ocurrir reiteradamente,
donde la rapidez es fundamental, con sus operadores cargados en los registros. El estado
del CPU a cada momento está determinado por el contenido de los registros. El
contenido de la memoria, obviamente, debe estar sincronizado con lo que ocurre dentro
de éste — pero el estado actual del CPU, lo que está haciendo, las indicaciones respecto
a las operaciones recién realizadas que se deben entregar al programa en ejecución,
están todas representadas en los registros. Se debe mantener esto en mente cuando
posteriormente se habla de todas las situaciones en que el flujo de ejecución debe ser
quitado de un proceso y entregado a otro. La relación de la computadora y del sistema
operativo con la memoria principal será abordada en el capítulo 5.
LAS TERMINALES: excepciones resultan en una señal enviada al proceso, y este
último es el encargado de tratar la excepción. En otros casos la falla o excepción son
irrecuperables (una instrucción inválida o un error de bus) ante la cual el sistema
operativo terminará el proceso que la generó. En el capítulo 5 se cubre con mucho
mayor detalle un tipo de excepción muy importante que debe tratar el sistema operativo:
el fallo de paginación. En los sistemas operativos modernos es común referirse al
emulador de terminal, un programa especializado, ya sea para tener múltiples instancias
de una terminal, o para ejecutar una terminal de texto dentro de una interfaz gráfica.
Estos programas se denominan de esta forma dado que sólo replican el comportamiento
de las terminales (que eran originalmente equipos independientes), siendo únicamente
un programa que recibe la entrada del usuario por medio del teclado enviándola al
sistema operativo como un flujo de datos, y recibe otro flujo de datos del sistema
operativo, presentándolo de forma adecuada al usuario.
Los dispositivos de almacenamiento (discos, memorias flash, cintas) pueden ser vistos
como una región donde la computadora lee y escribe una serie de bytes que preservarán
su valor, incluso luego de apagada la computadora. Para el hardware el sistema
operativo no accede al dispositivo de almacenamiento byte por byte, sino que éstos se
agrupan en bloques de tamaño fijo. El manejo de estos bloques (administración de
bloques libres, lectura y escritura) es una tarea fundamental del sistema operativo, que
asimismo se encarga de presentar abstracciones como la de archivos y directorios al
usuario. Hoy en día, el acomodo más frecuente6 de estos buses es por medio de una
separación en dos chips: el puente norte (Northbridge), conectado directamente al CPU,
encargado de gestionar los buses de más alta velocidad y que, además, son
fundamentales para el más básico inicio de la operación del sistema: la memoria y el
reloj. La comunicación con algunas tarjetas de video se incorpora al puente norte a
través del canal dedicado AGP (Advanced Graphics Port, Puerto Gráfico Avanzado). Al
puente norte se conecta el puente sur (Southbridge), que controla el resto de los
dispositivos del sistema. Normalmente se ven aquí las interfaces de almacenamiento
(SCSI, SATA, IDE), de expansión interna (PCI, PCIe) y de expansión externa (USB,
Firewire, puertos heredados seriales y paralelos).
Un proceso, a lo largo de su vida, alterna entre diferentes estados de ejecución. Éstos
son:
Nuevo Se solicitó al sistema operativo la creación de un proceso, y sus recursos y
estructuras están siendo creadas. Listo Está listo para iniciar o continuar su ejecución,
pero el sistema no le ha asignado un procesador. En ejecución El proceso está siendo
ejecutado en este momento. Sus instrucciones están siendo procesadas en algún
procesador. Bloqueado En espera de algún evento para poder continuar su ejecución
(aun si hubiera un procesador disponible, no podría avanzar). Zombi El proceso ha
finalizado su ejecución, pero el sistema operativo debe realizar ciertas operaciones de
limpieza para poder eliminarlo de la lista.1 Terminado El proceso terminó de ejecutarse;
sus estructuras están a la espera de ser limpiadas por el sistema operativo.
Equipo de trabajo al iniciar la porción multadillos del proceso, se crean muchos hilos
idénticos, que realizarán las mismas tareas sobre diferentes datos. Este modelo es
frecuentemente utilizado para cálculos matemáticos (p. ej.: criptografía, rendir, álgebra
lineal). Puede combinarse con un estilo jefe/trabajador para irle dando al usuario una pre
visualización del resultado de su cálculo, dado que éste se irá ensamblando
progresivamente, pedazo por pedazo. Su principal diferencia con el patrón
jefe/trabajador consiste en que el trabajo a realizar por cada uno de los hilos se plantea
desde principio, esto es, el paso de división de trabajo no es un hilo más, sino que
prepara los datos para que éstos sean lanzados en paralelo. Estos datos no son resultado
de eventos independientes (como en el caso anterior), sino partes de un solo cálculo.
Aunque una de las tareas principales de los sistemas operativos es dar a cada proceso la
ilusión de que se está ejecutando en una computadora dedicada, de modo que el
programador no tenga que pensar en la competencia por recursos, a veces un programa
requiere interactuar con otros: parte del procesamiento puede depender de datos
obtenidos en fuentes externas, y la cooperación con hilos o procesos externos es
fundamental. Se verá que pueden aparecer muchos problemas cuando se estudia la
interacción entre hilos del mismo proceso, la sincronización entre distintos procesos, la
asignación de recursos por parte del sistema operativo a procesos simultáneos, o incluso
cuando interactúan usuarios de diferentes computadoras de una red —se presentarán
distintos conceptos relacionados con la concurrencia utilizando uno de esos escenarios,
pero muchos de dichos conceptos en realidad son independientes del escenario: más
bien esta sección se centra en la relación entre procesos que deben compartir recursos o
sincronizar sus tareas. Para presentar la problemática y los conceptos relacionados con
la concurrencia suelen utilizarse algunos problemas clásicos, que presentan casos
particulares muy simplificados, y puede encontrárseles relación con distintas cuestiones
que un programador enfrentará en la vida real. Cada ejemplo presenta uno o más
conceptos. Se recomienda comprender bien el ejemplo, el problema y la solución y
desmenuzar buscando los casos límite como ejercicio antes de pasar al siguiente caso.
También podría ser útil imaginar en qué circunstancia un sistema operativo se
encontraría en una situación similar, Para profundizar más en este tema, se recomienda
el libro The little book of semaphores (Downey 2008). En este libro (de libre descarga)
se encuentran muchos ejemplos que ilustran el uso de semáforos, no sólo para resolver
problemas de sincronización, sino como un mecanismo simple de comunicación entre
procesos. También se desarrollan distintas soluciones para los problemas clásicos (y no
tan clásicos).
Por otro lado, uno podría pensar (con cierta cuota de razón) que la secuencia de eventos
propuesta es muy poco probable: usualmente un sistema operativo ejecuta miles de
instrucciones antes de cambiar de un proceso a otro. De hecho, en la práctica este
problema es muy frecuentemente ignorado y los programas funcionan muy bien la
mayoría de las veces. Esto permite ver una característica importante de los programas
concurrentes: es muy usual que un programa funcione perfectamente la mayor parte del
tiempo, pero de vez en cuando puede fallar. Subsecuentes ejecuciones con los mismos
argumentos producen nuevamente el resultado correcto. Esto hace que los problemas de
concurrencia sean muy difíciles de detectar y más aún de corregir. Es importante (y
mucho más efectivo) realizar un buen diseño inicial de un programa concurrente en
lugar de intentar arreglarlo cuando se detecta alguna falla. También es interesante notar
que, dependiendo del sistema, puede ser que alguna de las instrucciones sea muy lenta,
en el caso de un sistema de reserva de asientos de aviones, las operaciones pueden durar
un tiempo importante (p. ej.: desde que el operador muestra los asientos disponibles
hasta que el cliente lo elige) haciendo mucho más probable que ocurra una secuencia no
deseada.
Si bien este análisis presenta aparentemente una problemática específica al
planteamiento en cuestión es fácil ver que la misma circunstancia podría darse en un
sistema de reserva de vuelos (p. ej.: puede que dos operadores vean un asiento vacío en
su copia local de los asientos y ambos marquen el mismo asiento como ocupado) o con
dos procesos que decidan cambiar simultáneamente datos en un archivo. Aquí las
operaciones ya no son necesariamente internas de la máquina.
Otra cuestión que puede parecer artificiosa es que en el ejemplo hay un solo procesador
o núcleo. Sin embargo, tener más de un procesador no sólo no soluciona el problema,
sino que lo empeora: ahora las operaciones de lectura o escritura pueden ejecutarse
directamente en paralelo y aparecen nuevos problemas de coherencia de caché. En la
siguiente discusión muchas veces se presupone que hay un solo procesador, sin que eso
invalide la discusión para equipos multiprocesadores.
Manipulación de datos que requiere la garantía de que se ejecutará como una sola
unidad de ejecución, o fallará completamente, sin resultados o estados parciales
observables por otros procesos o el entorno. Esto no necesariamente implica que el
sistema no retirará el flujo de ejecución en medio de la operación, sino que el efecto de
que se le retire el flujo no llevará a un comportamiento inconsistente.
Dado que el sistema no tiene forma de saber cuáles instrucciones (o áreas del código)
deben funcionar de forma atómica, el programador debe asegurar la atomicidad de
forma explícita, mediante la sincronización de los procesos. El sistema no debe permitir
la ejecución de parte de esa área en dos procesos de forma simultánea (sólo puede haber
un proceso en la sección crítica en un momento dado).

Vous aimerez peut-être aussi