Unidad 1 Introducción a los sistemas operativos

Anuncio
Unidad 1 Introducción a los sistemas operativos
1.1 Definición, Objetivos, y Función Sistema Operativo
Definición de Sistema Operativo
El sistema operativo es el programa (o software) más importante de un
ordenador. Para que funcionen los otros programas, cada ordenador de uso
general debe tener un sistema operativo. Los sistemas operativos realizan
tareas básicas, tales como reconocimiento de la conexión del teclado, enviar la
información a la pantalla, no perder de vista archivos y directorios en el disco, y
controlar los dispositivos periféricos tales como impresoras, escáner, etc. En
sistemas grandes, el sistema operativo tiene incluso mayor responsabilidad y
poder, es como un policía de tráfico, se asegura de que los programas y
usuarios que están funcionando al mismo tiempo no interfieran entre ellos. El
sistema operativo también es responsable de la seguridad, asegurándose de
que los usuarios no autorizados no tengan acceso al sistema. Clasificación de
los Sistemas Operativos Los sistemas operativos pueden ser clasificados de la
siguiente forma: •Multiusuario: Permite que dos o más usuarios utilicen sus
programas al mismo tiempo. Algunos sistemas operativos permiten a centenares
o millares de usuarios al mismo tiempo. •Multiprocesador: soporta el abrir un
mismo programa en más de una CPU. •Multitarea: Permite que varios
programas se ejecuten al mismo tiempo. •Multitramo: Permite que diversas
partes de un solo programa funcionen al mismo tiempo. •Tiempo Real:
Responde a las entradas inmediatamente. Los sistemas operativos como DOS y
UNIX, no funcionan en tiempo real. Cómo funciona un Sistema Operativo Los
sistemas operativos proporcionan una plataforma de software encima de la cual
otros programas, llamados aplicaciones, puedan funcionar. Las aplicaciones se
programan para que funcionen encima de un sistema operativo particular, por
tanto, la elección del sistema operativo determina en gran medida las
aplicaciones que puedes utilizar. Los sistemas operativos más utilizados en los
PC son DOS, OS/2, y Windows, pero hay otros que también se utilizan, como
por ejemplo Linux. Cómo se utiliza un Sistema Operativo Un usuario
normalmente interactúa con el sistema operativo a través de un sistema de
comandos, por ejemplo, el sistema operativo DOS contiene comandos como
copiar y pegar para copiar y pegar archivos respectivamente. Los comandos son
aceptados y ejecutados por una parte del sistema operativo llamada procesador
de comandos o intérprete de la línea de comandos. Las interfaces gráficas
permiten que utilices los comandos señalando y pinchando en objetos que
aparecen en la pantalla.
Ejemplos de Sistema Operativo A continuación detallamos algunos ejemplos de
sistemas operativos: Familia Windows •Windows 95 •Windows 98 •Windows ME
•Windows NT •Windows 2000 •Windows 2000 server •Windows XP •Windows
Server 2003 •Windows CE •Windows Mobile •Windows XP 64 bits •Windows
Vista (Longhorn)
Familia Macintosh •Mac OS 7 •Mac OS 8 •Mac OS 9 •Mac OS X
Familia UNIX •AIX •AMIX •GNU/Linux •GNU / Hurd •HP-UX •Irix •Minix •System
V •Solaris •Unix Ware?
El objetivo fundamental de los sistemas operativos
Es gestionar y administrar eficientemente los recursos hardware, permitiendo
que se ejecuten concurrentemente varios programas, sin que haya conflictos en
el acceso de cada uno de ellos a cada uno de los recursos que necesite, y sin
que ningún programa monopolice alguno de ellos. Un sistema operativo es un
programa (o conjunto de programas) de control que tiene por objeto facilitar el
uso de la computadora y conseguir que ésta se utilice eficientemente. Es un
programa de control, ya que se encarga de gestionar y asignar los recursos
hardware que requieren los programas. Pensemos en una computadora que es
utilizada desde diversos terminales por varios usuarios. Los recursos hardware
son: el procesador (CPU), la memoria principal, los discos, y otros periféricos.
Obviamente, si varios usuarios están utilizando la misma Computadora, debe
haber alguien o algo que asigne los recursos y evite los conflictos que puedan
surgir cuando dos programas requieran los mismos elementos (la misma unidad
de disco, o la impresora, por ejemplo). Esta es una de las funciones del sistema
operativo. Además de esta función de asignar los recursos a cada programa, el
sistema operativo se encarga de contabilizar de éstos, y de la seguridad (que un
usuario no pueda acceder sin autorización a la información de otro, por ejemplo).
El sistema operativo facilita el uso de la computadora. Veamos un ejemplo de
cómo lo hace. Cada dispositivo de E/S, para ser utilizado, requiere varias
instrucciones máquina que establezcan un dialogo entre las unidades centrales y
el periférico, enviando o captando el dato de salida o de entrada,
respectivamente. Estas instrucciones dependen considerablemente de las
características concretas del periférico. Si se trata, por ejemplo, de una unidad
de disco, hay que considerar el ancho de los buses, el tamaño de su memoria
intermedia, el arranque (y parada) de los motores de la unidad, el código
identificador de la posición a donde hay que acceder, etc. Por otra parte, un
dispositivo dado, estas instrucciones u operaciones son comunes para grabar o
leer cual tipo de información (programas o datos), sea cual sea su naturaleza. El
sistema operativo, con objetivo de facilitar el trabajo de los programadores,
contiene módulos de gestión de entradas / salidas que evitan a los usuarios
tener que incluir esas instrucciones cada vez que hacen una operación de
entrada o salida. Se puede decir que esos programas del sistema operativo
hacen transparente al usuario las características hardware concretas de los
dispositivos. El sistema operativo también hace que la computadora se utilice
eficientemente. Para poner de manifiesto cómo el sistema operativo puede
incrementar la eficiencia consideremos un ejemplo sencillo. Los programas
tradicionalmente se ejecutan secuencialmente; es decir, hasta que no concluye
la ejecución de una instrucción no se ejecuta la siguiente. Supongamos que
dentro de un programa hay una instrucción que implica la escritura de una
página en una impresora láser. Hasta que no acabe de imprimirse dicha página
el programa no puede continuar ejecutándose. En resumen, el sistema operativo
efectúa, entre otras, las siguientes funciones: - Facilita el uso de la computadora,
en general, la comunicación computadora / usuario - Gestiona y asigna recursos
hardware (procesador, memoria y periféricos) a los distintos programas o tareas
- Gestiona y mantiene los archivos en dispositivos de memoria masiva - Apoya a
otros programas - Protege los datos y los programas, cuestión especialmente
compleja en sistemas multiusuario - Identifica y autentifica a los usuarios que
hacen uso de la computadora. - Contabiliza la utilización de los recursos
realizada por los distintos usuarios
Sus funciones mas importantes son:
-Gestiona los recursos del ordenador en sus niveles mas bajos. -Dispone de una
interface (elemento que hace posible la fácil comunicación usuario maquina)
liberando al usuario del conocimiento del hardware. El SO windows se basa en
una interface graficas, “GUI” (Interface Grafica de Usuario), permitiendo al
usuario interactuar con el hardware de una forma sencilla y rápida. -Sobre el SO
funcionan el resto de programas y aplicaciones del software.
Sus generaciones:
-Generación 0º: década de los 40 los sistemas informáticos no disponían de SO
con lo que los usuarios de estos debían introducir las instrucciones en código
binario lo que hacia su uso restringido a personas de mucho conocimiento en
esa materia. -Generación 1º: década de los 50. Aparece el primer SO para lograr
la fluidez en la trasmisión de información. Aparece el JLC (lenguaje de control de
trabajo), se usaban tarjetas perforadas y eran controladas por operadores
(personas con cierto conocimiento). Posteriormente se pasaron de las tarjetas a
las cintas perforadas y estas iban mucho mas rápido. En el primer SO había en
ocupaba en memoria 64 KB (bastante en función de la capacidad total de la
memoria en aquella época).
Grafico interno de un sistema operativo de la época y en parte en la actualidad
Generación 2º: Se dan los primeros pasos de la multiprogramación es decir
varios programas de usuario. El SO reparte tiempos del procesador. Aparece la
llamada tecnología DMA usa buffers entre terminales: impresora, etc. ¿Qué es
un buffer?: Es una fuente de almacenamiento temporal que reside en el propio
dispositivo ya sea de entrada, o de salida. Aparece el termino spooding: viene a
ser como lo que gestiona la cola de instrucciones en el buffer.
Terminales Impresora
Durante esta generación aparecen los primeros multiprocesarodes (varios
procesadores trabajando simultáneamente, a la vez).
Generación 3º: segunda mitad de la década de los 60 y 1º mitad de los 70. Es
entonces cuando se desarrollan los SO tan importantes como el UNÍS para la
gestión de grandes mainframes. Durante esta generación el usuario perdió el
control del hardware. Los equipos informáticos venían con el software (SO) de
“regalo”.
Generación 4º: segunda mitad de los 70 y primera de los 80. Los SO aumentan
sus prestaciones y gestionan eficientemente los recursos del ordenador. Es en
esta época donde mas facilidad se le da al usuario para su manejo. IBM separa
los costos de hardware y software con esta estrategia de marketing se pensaba
que facturarían el doble en ganancias. Pero no fue así. Los vendedores de
software pasan a hacerse responsables de los bugs (o fallos de sus programas).
Proliferaron las empresas desarrolladoras de software esto perjudico seriamente
a IBM ya que así perdió la exclusividad. Posteriormente se abrió el mercado de
computadoras compatibles con IBM, estos son los llamados clónicos (varios
dispositivos informáticos de distintas fabricas o procedencias intercomunicados y
compatibles entre si constituyendo un único equipo informático. Este tipo de
ordenadores es de precio mucho mas reducido que los IBM y sus prestaciones
son las mismas).
Generación 5º: década de los 90. Los entornos gráficos cobraron mucha
importancia, proliferaron y evolucionaron las llamadas GUIs (interfaces graficas
del usuario). Los sistemas operativos tipo windows 9*, millenium o NT para
empresas proliferaron y desplazaron de las empresas al ya consolidado UNÍS.
Una de las características he imnovaciones mas importantes de un SO es la
llamada multi-tarea. Un SO opera entre la CPU y los periféricos y con la
tecnología multi-tarea reparte el tiempo entre ellos dos. Suponiendo que se
lancen tres procesos (A,B,C), (proceso: conjunto de rutina, algoritmos, etc.). Lo
que el SO hace internamente con esta tecnología es: recoger la primera
operación del proceso A en CPU luego pasa a los periféricos con lo que la CPU
descansa y en ese momento, recoge la primera operación del proceso B en
CPU, posteriormente en cuanto va a los periféricos pasa al proceso C, y cuando
a este le llegan los turnos que corresponden a los periféricos pasa a la segunda
operación del proceso A. Y asi sucesivamente. Con esta tecnología se logra
apurar y reducir enormemente el tiempo de proceso del SO, podemos llegar a
unas 50 tareas simultáneamente. Sistemas operativos como, el ms-dos no
disponen de ella, pero otros como windows si alcanzan esta tecnología.
Y con esto doy por finalizado el tutorial de componentes que incluyen un equipo
informático.
Mulprogramacion o multiproceso: Es la técnica que permite cargar varios
programas o procesos al mismo tiempo de forma simultanea.
Cada programa o proceso ha de usar unos recursos y el SO ha de gestionar
esto. Se pueden dar los llamados interbloqueos en la que 2 o mas programas
estan a la espera por solicitar un dispositivo o memoria. El SO debe solucionar
esto.
Batch: sirve para aprovechar tiempos muertos (noches), etc. En grandes
empresas los usan para hacer copias de seguridad.
Tiempo real: Asigna de forma primaria unos tiempos si se pasa de ellos da paso
al siguiente.
Seguridad: El SO debe suministrar los medios para la ejecución concurrente de
los procesos, sincronizacion entre procesos, comunicación entre procesos. El
SO debe suministrar algoritmos de gestion y planificación de procesos que se
encarguen de decidir que proceso se ejecutara o cual tomara al procesador y de
llevar cuenta de los estados y procesos, sus prioridades y todo la restante
información relevante.
Estado de los procesos Activo: Ejecutándose en un instante de tiempo. En un
sistema monoprocesador, solo puede haber uno. Preparado: Listos para
ejecutarse. Esperando que un procesador quede libre, bloqueado o suspendido,
a la espera de que se cumpla una condición. Muerto: Ha terminado su ejecución
o el sistema ha detectado un error fatal y la ha transferido ha estado nonato.
Nonato: El programa existe pero todavía no es conocido por el SO.
El estado global del SO en un instante determinado, es el conjunto de recursos y
procesos existentes con sus estados correspondientes
Transición entre procesos
El distribuidor: es uin modulo del SO que activa procesos preparados de acuerdo
con unos criterios determinados por ejemplo: prioridad. Interrupción: Son las
llamadas del SO para solicitar servicios por ejemplo: una operación.de E/S.
Planificador: Modulo del SO que translada procesos de ejecución a preparados,
por ejemplo: en sistemas de tiempo compartido porque se les ajusta el tiempo. O
llega uno de mayor prioridad. Paso de preparado a bloqueado: Cuando tiene
lugar un evento que estuviera esperando para poder perseguirlo
1.2 Historia Evolución Sistema Operativo
Introducción
Los sistemas operativos han venido evolucionando a través de los años. Ya que
los sistemas operativos se han apegado íntimamente a la arquitectura de las
computadoras en las cuales se ejecutan.
La primera computadora digital real fue diseñada por el matemático ingles
Charles Babbage ( 1792 - 1871) . Aunque Babbage gasto la mayor parte de su
vida y de su fortuna intentando construir su “ maquina analítica “ , nunca la hizo
funcionar adecuadamente porque era un diseño puramente mecánico y la
tecnología de su época no podía producir las ruedas, el engranaje, levas y otras
partes mecánicas con la alta precisión que el necesitaba. Sin tener que decirlo,
la maquina analítica no tuvo un sistema operativo.
La primera generación (1945 - 1955 ) : Tubos de vacio y tableros enchufables
Después de los esfuerzos frustrados de Babbage, se progresó poco en la
construcción de computadoras digitales hasta la segunda guerra mundial,
alrededor de la mitad de la década de 1940, Howard Aiken en Hardvard, Jon
Von Neumann en el Instituto de Estudios Avanzados en Princeton, J. Presper
Ecker y William Mauchley en la Universidad de Pennsylvania y Konrad Zuse en
Alemania, entre otros, todos obtuvieron resultados óptimos en la construcción de
maquinas de calculo mediante el uso de tubos de vacío.
En estos primeros días, un grupo singular de personas diseño, construyo,
programo, opero y dio mantenimiento a cada maquina. Toda la programación se
realizo en lenguaje de maquina absoluto. Los lenguajes de programación se
desconocían ( todavía no existía el lenguaje ensamblador ). Los primeros
sistemas operativos eran extraños. El modo usual de operación consistía en que
el programador firmaba para tener acceso a un bloque de tiempo en la hoja de
registro situada en la pared, después bajaba al cuarto de maquinas, insertaba su
tablero enchufable en la computadora y pasaba las siguientes horas esperando
que ninguno de los 20,000 tubos de vació se fundiera durante la ejecución de su
programa.
Al inicio de la década de 1950, la rutina había mejorado un poco con la
introducción de la tarjetas perforadas. Ahora era posible escribir en tarjetas y
leerlos, en vez de utilizar tableros enchufables; de lo contrario el procedimiento
era el mismo.
La segunda generación (1955 - 1965 ) : Transistores y sistemas de lote
La introducción del transistor a mediados de la década de 1950 cambio la
imagen radicalmente. Las computadoras se volvieron lo suficientemente
confiables, en un principio hubo una clara separación entre los diseñadores,
armadores, operadores, programadores y personal de mantenimiento. Estas
maquinas se instalaban en cuartos de computadoras especialmente
acondicionados con aire, con cuerpo de operadores profesionales para
accionarlas. un programador primeramente escribiría el programa en papel ( en
FORTRAN o en lenguaje Ensamblador ) y después lo perforaría en tarjetas.
Después llevaría la pila de tarjetas al cuarto de introducción al sistema y la
entregaría a uno de los operadores el cual iniciaba el proceso en la
computadora, este proceso desperdiciaba mucho tiempo.
Dado el alto costo del equipo, no es sorprendente que las personas buscaran
rápidamente maneras de reducir el tiempo perdido. La solución que
generalmente se adoptaba era el sistema de lote. La idea implícita en este
sistema era la de conjuntar un cajón lleno de trabajos en el cuarto de
introducción al sistema y después leerlos en una cinta magnética mediante el
uso de una computadora ( relativamente ) pequeña y poco costosa, como la IBM
1401.
Después de casi una hora de recolectar un lote de trabajos, la cinta se volvía a
enrollar y se llevaba al cuarto de maquinas. Después el operador cargaba un
programa especial ( el ancestro del sistema operativo de hoy en día ) , el cual
leía el primer trabajo y lo ejecutaba, la salida se escribía en una segunda cinta,
en vez de imprimirse. Después de terminar cada trabajo, el sistema operativo
leía automáticamente el siguiente trabajo de la cinta, y comenzaba a ejecutarlo.
La estructura de un trabajo de entrada común arrancaba con una tarjeta $JOB ,
que especifica el tiempo máximo de ejecución en minutos, el numero de cuenta
que se cargara y el nombre del programador. Después venia una tarjeta
$FORTRAN , que indicaba al sistema operativo que debía cargar el compilador
de FORTRAN . Venia seguido de un programa que debía compilarse y después
de una tarjeta $LOAD, que ordenaba al sistema operativo cargar el programa
objeto recién compilado, después venia la tarjeta $RUN, que indicaba al sistema
operativo que debía ejecutar el programa con los datos que le seguían. Por
ultimo, la tarjeta $END marcaba el final del trabajo. Los sistemas operativos
comunes eran FMS ( el sistema monitor del FORTRAN ) e IBSYS, sistema
operativo de IBM de la 7094.
La tercera generacion (1965 - 1980 ) : Circuitos integrados ( CI ) y
multiprogramacion Al inicio de la década de 1960 muchos fabricantes de
computadoras tenían dos líneas de trabajo distintas y totalmente incompatibles.
Por un lado existían las computadoras científicas de grande escala orientadas a
las palabras, como la 7094, que se utilizaban para realizar cálculos numéricos
de ciencias e ingeniería. Por el otro lado estaban las computadoras comerciales
orientadas a los caracteres, como 1401, que se utilizaban para el ordenamiento
de cintas e impresión por parte de bancos y compañías de seguros.
El desarrollo y mantenimiento de dos líneas de productos diferentes era una
proposición costosa para los fabricantes. Además, muchos nuevos compradores
de computadoras necesitaban una maquina pequeña, pero después se
expandían y querían una maquina de mayor tamaño que ejecutara todos sus
programas antiguos, pero con mayor velocidad.
IBM intento resolver estos dos problemas de un solo golpe introduciendo en el
mercado el Sistema/360. El 360 era una serie de maquinas compatibles con el
software que variaban del tamaño de la 1401 a una mucho mas poderosa que la
7094, el 360 estaba diseñado para realizar cálculos tanto científicos como
comerciales. Por lo tanto una sola familia de maquinas podía satisfacer las
necesidades de todos los clientes.
El sistema 360 fue la primera línea importante de computadoras que utilizo
circuitos integrados ( CI ), con lo cual ofreció una mayor ventaja de
precio/rendimiento sobre las maquinas de la segunda generación.
La intención era que todo el software, como el sistema operativo, tenían que
funcionar en todos los modelos. Tenia que correr en sistemas pequeños, y en
sistemas muy grandes. Tenia que funcionar adecuadamente en sistemas con
algunos periféricos y en sistemas con muchos periféricos.
No había manera de que IBM escribiera una pieza de software que cumpliera
todos esos requisitos conflictivos. El resultado fue un sistema operativo enorme
y extraordinariamente complejo. Constaba de millones de líneas de lenguaje
ensamblador escritas por miles de programadores, y contenía miles y miles de
errores ocultos.
A pesar de tamaño y problemas enormes , OS/360 y los sistemas operativos
similares de la tercera generación satisfacían a muchos de sus clientes
razonablemente bien, También popularizaron varias técnicas importantes
ausentes en los sistemas operativos de la segunda generación. La mas
importante de estas fue la multiprogramación. Cuando el trabajo corriente se
detenía para esperara a que se completara una operación en cinta u otra
operación de E/S, la unidad central de procesamiento ( CPU ) simplemente
permanecía ociosa hasta que terminara la operación de E/S . La solución que
evoluciono consistía en partir la memoria en varias partes, con trabajo diferente
en cada partición. Mientras que un trabajo esperaba a que se completara la E/S,
otro trabajo podía estar utilizando la CPU. Si se podían mantener suficientes
trabajos en la memoria central al mismo tiempo, la CPU podía mantenerse
ocupada casi el 100% del tiempo.
Otra característica de importancia en los sistemas operativos de la tercera
generación era la capacidad de leer trabajos de tarjetas contenidas en el disco
tan pronto como se llevaban al cuarto de computación. Siempre que se
terminaba un trabajo, el sistema operativo podía cargar uno nuevo del disco en
la partición no vacía y ejecutarlo, esta técnica se denomina manejo por cola de
impresión.
Los sistemas operativos de la tercera generación seguían siendo básicamente
sistemas de lote. Con los sistemas operativos de la tercera generación, el tiempo
entre la entrega de un trabajo y la devolución de la salida comprendía a menudo
varias horas.
El deseo de obtener un tiempo de respuesta corto marco el camino para el
tiempo compartido, variante de la multiprogramación, en la cual cada usuario
tiene una terminal en línea. En un sistema de tiempo compartido si hay 20
usuarios dentro del sistema y 17 de ellos están pensando o platicando o bien
tomando café, la CPU puede distribuirse en turno para los tres trabajos que
necesitan servicio. Aunque el primer sistema de tiempo compartido ( CTSS )
serio fue creado en MIT en una unidad 7094 especialmente modificada, no se
volvió popular sino hasta que el hardware de protección necesario se disemino
durante la tercera generación.
Después del éxito del sistema CTSS, MIT, Bell laboratories y General electric
decidieron embarcarse en el desarrollo de la “ computadora de servicio publico “.
conocido como MULTICS ( Multiplexed information and computing service,
información multicanalizada y servicio de computación ) . Para resumir una larga
historia, MULTICS introdujo muchas ideas originales en la literatura de
computación, pero su construcción era mas difícil de lo que nadie había
sospechado. MULTICS tuvo enorme influencia sobre otros sistemas
subsiguientes. Otro avance durante la tercera generación fue el crecimiento de
las minicomputadoras, comenzando con DEC PDP-1 en 1961. Uno de los
científicos que había trabajado en el proyecto MULTICS, Ken Thompson, hallo
después una pequeña PDP-7 y empezó a escribir después una versión
desguarnecida de MULTICS para un usuario. Este sistema se llamo “UNICS” (
Uniplexed information and computing service, información unicanalizada y
servicio de computación ), pero su ortografía cambio mas tarde por UNIX. UNIX
se ha desplazado a mas computadoras que ningún otro sistema operativo de la
historia y su uso sigue aumentando rápidamente.
La cuarta generacion (1980 - 1990 ) : Computadoras personales
Con la creación de los circuitos integrados LSI ( integración a grande escala ) ,
chips que contiene miles de transistores en un centímetro cuadrado de silicon, la
era de computadora personal vio sus inicios. Dos sistemas operativos han
dominado la escena de la computadora personal: MS-DOS, escrito por
Microsoft, Inc., para la IBM PC y otras computadoras que utilizan la CPU Intel
8088 y sus sucesores. y UNIX, que domina en las computadoras personales
mayores que hacen uso de CPU Motorola 68000. Aunque la versión inicial de
MS-DOS era relativamente primitiva, versiones subsiguientes han incluido mas y
mas características de UNIX, lo que no es totalmente sorprendente dado que
Microsoft es un proveedor importante de UNIX, que usa el nombre comercial de
XENIX. Un avance importante que empezó a tomar su sitio a mediados de la
década de 1980 es el desarrollo de redes de computadoras personales que
corren sistemas operativos en red y sistemas operativos distribuidos. En un
sistema operativo en red, los usuarios tienen conocimiento de la existencia de
múltiples computadoras y pueden ingresar en maquinas remotas y reproducir
archivos de una maquina a la otra. Cada maquina ejecuta su sistema operativo
local y tiene un usuario propio ( o usuarios). Un sistema distribuido, es aquel que
se presenta ante sus usuarios como un sistema uniprocesador tradicional,
aunque en realidad este compuesto de múltiples procesadores. En un sistema
distribuido real, los usuarios no tienen conocimiento de donde se están
ejecutando sus programas o de donde están ubicados sus archivos; todo esto se
debe manejar en forma automática y eficiente por medio del sistema operativo.
Los sistemas operativos en red no son fundamentalmente diferentes de los
sistemas operativos uniprocesadores. Sin duda necesitan un controlador de
interfaz en red y algún software de bajo nivel para impulsarlo, así como
programas para lograr un ingreso remoto al sistema y un acceso remoto del
archivo . Los sistemas operativos distribuidos reales requieren mas que
simplemente agregar un poco de código a un sistema operativo uniprocesador,
ya que los sistemas operativos distribuidos y centralizados difieren de manera
decisiva.
Historia de Minix
Cuando UNIX era joven ( versión 6 ), el código fuente se encontraba en todas
partes, con autorización de AT&T, y se estudiaba frecuentemente, John Lions,
llego a escribir un pequeño folleto que describía su operación, línea por línea,
este folleto se utilizo como libro de texto en muchos cursos universitarios.
Cuando AT&T entrego la versión 7, empezó a comprender que UNIX era un
valioso producto comercial, así que emitió la versión 7 con una licencia que
prohibía el estudio del código fuente en cursos con el objeto de evitar poner en
peligro su condición como secreto comercial, muchas universidades se quejaron
simplemente descartando el estudio de UNIX y enseñando solo teoría. Por
desgracia, el solo enseñar teoría deja al estudiante con una visión
desproporcionada de lo que en realidad es un sistema operativo. Para remediar
esta situación, decidí escribir un nuevo sistema operativo que seria compatible
con UNIX desde el punto de vista del usuario, pero completamente diferente en
el interior. El nombre MINIX surge de mini-UNIX porque es lo suficientemente
pequeño que hasta alguien que no sea maestro puede entender la forma en que
trabaja. MINIX tiene otra ventaja sobre UNIX, se escribió una década después
que UNIX y se ha estructurado en forma mas modular. El sistema de archivo de
MINIX , por ejemplo, no es parte del sistema operativo en absoluto, pero corre
como un programa de usuario. Otra diferencia es que UNIX se diseño para ser
eficiente; MINIX se diseño para ser legible, el código de MINIX, por ejemplo ,
tiene mas de 3000 comentarios en él. MINIX se ha diseñado para ser compatible
con la versión 7 de UNIX. AL igual que UNIX, MINIX se escribe en lenguaje de
programación C. La implementacion inicial se hizo en la IBM PC, MINIX no
requiere un disco duro para correr, con lo cual se ajusta a los presupuestos de
muchos estudiantes
Historia de los sistemas operativos
Los Sistemas Operativos, al igual que el Hardware de los computadores, han
sufrido una serie de cambios revolucionarios llamados generaciones. En el caso
del Hardware, las generaciones han sido marcadas por grandes avances en los
componentes utilizados, pasando de válvulas ( primera generación ) a
transistores ( segunda generación ), a circuitos integrados ( tercera generación),
a circuitos integrados de gran y muy gran escala (cuarta generación). Cada
generación Sucesiva de hardware ha ido acompañada de reducciones
substanciales en los costos, tamaño, emisión de calor y consumo de energía, y
por incrementos notables en velocidad y capacidad.
Generación Cero (década de 1940)
Los primeros sistemas computacionales no poseían sistemas operativos. Los
usuarios tenían completo acceso al lenguaje de la maquina. Todas las
instrucciones eran codificadas a mano.
Primera Generación (década de 1950)
Los sistemas operativos de los años cincuenta fueron diseñados para hacer mas
fluida la transición entre trabajos. Antes de que los sistemas fueran diseñados,
se perdía un tiempo considerable entre la terminación de un trabajo y el inicio del
siguiente. Este fue el comienzo de los sistemas de procesamiento por lotes,
donde los trabajos se reunían por grupos o lotes. Cuando el trabajo estaba en
ejecución, este tenia control total de la maquina. Al terminar cada trabajo, el
control era devuelto al sistema operativo, el cual limpiaba y leía e iniciaba el
trabajo siguiente.
Al inicio de los 50′s esto había mejorado un poco con la introducción de tarjetas
perforadas (las cuales servían para introducir los programas de lenguajes de
máquina), puesto que ya no había necesidad de utilizar los tableros enchufables.
Además el laboratorio de investigación General Motors implementó el primer
sistema operativo para la IBM 701. Los sistemas de los 50′s generalmente
ejecutaban una sola tarea, y la transición entre tareas se suavizaba para lograr
la máxima utilización del sistema. Esto se conoce como sistemas de
procesamiento por lotes de un sólo flujo, ya que los programas y los datos eran
sometidos en grupos o lotes.
La introducción del transistor a mediados de los 50′s cambió la imagen
radicalmente.
Se crearon máquinas suficientemente confiables las cuales se instalaban en
lugares especialmente acondicionados, aunque sólo las grandes universidades y
las grandes corporaciones o bien las oficinas del gobierno se podían dar el lujo
de tenerlas.
Para poder correr un trabajo (programa), tenían que escribirlo en papel (en
Fortran o en lenguaje ensamblador) y después se perforaría en tarjetas.
Enseguida se llevaría la pila de tarjetas al cuarto de introducción al sistema y la
entregaría a uno de los operadores. Cuando la computadora terminara el
trabajo, un operador se dirigiría a la impresora y desprendería la salida y la
llevaría al cuarto de salida, para que la recogiera el programador.
Segunda Generación (a mitad de la década de 1960)
La característica de los sistemas operativos fue el desarrollo de los sistemas
compartidos con multiprogramación, y los principios del multiprocesamiento. En
los sistemas de multiprogramación, varios programas de usuario se encuentran
al mismo tiempo en el almacenamiento principal, y el procesador se cambia
rápidamente de un trabajo a otro. En los sistemas de multiprocesamiento se
utilizan varios procesadores en un solo sistema computacional, con la finalidad
de incrementar el poder de procesamiento de la maquina.
La independencia de dispositivos aparece después. Un usuario que desea
escribir datos en una cinta en sistemas de la primera generación tenia que hacer
referencia especifica a una unidad de cinta particular. En la segunda generación,
el programa del usuario especificaba tan solo que un archivo iba a ser escrito en
una unidad de cinta con cierto numero de pistas y cierta densidad.
Se desarrollo sistemas compartidos, en la que los usuarios podían acoplarse
directamente con el computador a través de terminales. Surgieron sistemas de
tiempo real, en que los computadores fueron utilizados en el control de procesos
industriales. Los sistemas de tiempo real se caracterizan por proveer una
respuesta inmediata.
Tercera Generación (mitad de década 1960 a mitad década de 1970)
Se inicia en 1964, con la introducción de la familia de computadores
Sistema/360 de IBM. Los computadores de esta generación fueron diseñados
como sistemas para usos generales . Casi siempre eran sistemas grandes,
voluminosos, con el propósito de serlo todo para toda la gente. Eran sistemas de
modos múltiples, algunos de ellos soportaban simultáneamente procesos por
lotes, tiempo compartido, procesamiento de tiempo real y multiprocesamiento.
Eran grandes y costosos, nunca antes se había construido algo similar, y
muchos de los esfuerzos de desarrollo terminaron muy por arriba del
presupuesto y mucho después de lo que el planificador marcaba como fecha de
terminación.
Estos sistemas introdujeron mayor complejidad a los ambientes
computacionales; una complejidad a la cual, en un principio, no estaban
acostumbrados los usuarios.
Cuarta Generación (mitad de década de 1970 en adelante)
Los sistemas de la cuarta generación constituyen el estado actual de la
tecnología. Muchos diseñadores y usuarios se sienten aun incómodos, después
de sus experiencias con los sistemas operativos de la tercera generación.
Con la ampliación del uso de redes de computadores y del procesamiento en
línea los usuarios obtienen acceso a computadores alejados geográficamente a
través de varios tipos de terminales.
Los sistemas de seguridad se ha incrementado mucho ahora que la información
pasa a través de varios tipos vulnerables de líneas de comunicación. La clave de
cifrado esta recibiendo mucha atención; han sido necesario codificar los datos
personales o de gran intimidad para que; aun si los datos son expuestos, no
sean de utilidad a nadie mas que a los receptores adecuados.
El porcentaje de la población que tiene acceso a un computador en la década de
los ochenta es mucho mayor que nunca y aumenta rápidamente.
El concepto de maquinas virtuales es utilizado. El usuario ya no se encuentra
interesado en los detalles físicos de; sistema de computación que esta siendo
accedida. En su lugar, el usuario ve un panorama llamado maquina virtual
creado por el sistema operativo.
Los sistemas de bases de datos han adquirido gran importancia. Nuestro mundo
es una sociedad orientada hacia la información, y el trabajo de las bases de
datos es hacer que esta información sea conveniente accesible de una manera
controlada para aquellos que tienen derechos de acceso.
1.3 Subsistemas de Sistemas Operativos
TIPOS DE SISTEMAS OPERATIVOS En esta sección se describirán las
características que clasifican a los sistemas operativos, básicamente se cubrirán
tres clasificaciones: sistemas operativos por su estructura (visión interna),
sistemas operativos por los servicios que ofrecen y, finalmente, sistemas
operativos por la forma en que ofrecen sus servicios (visión externa). 2.1
Sistemas Operativos por su Estructura Según [Alcal92], se deben observar dos
tipos de requisitos cuando se construye un sistema operativo, los cuales son:
Requisitos de usuario: Sistema fácil de usar y de aprender, seguro, rápido y
adecuado al uso al que se le quiere destinar. Requisitos del software: Donde se
engloban aspectos como el mantenimiento, forma de operación, restricciones de
uso, eficiencia, tolerancia frente a los errores y flexibilidad. A continuación se
describen las distintas estructuras que presentan los actuales sistemas
operativos para satisfacer las necesidades que de ellos se quieren obtener. 2.1.1
Estructura monolítica. Es la estructura de los primeros sistemas operativos
constituídos fundamentalmente por un solo programa compuesto de un conjunto
de rutinas entrelazadas de tal forma que cada una puede llamar a cualquier otra
(Ver Fig. 2). Las características fundamentales de este tipo de estructura son:
Construcción del programa final a base de módulos compilados separadamente
que se unen a través del ligador. Buena definición de parámetros de enlace
entre las distintas rutinas existentes, que puede provocar mucho acoplamiento.
Carecen de protecciones y privilegios al entrar a rutinas que manejan diferentes
aspectos de los recursos de la computadora, como memoria, disco, etc.
Generalmente están hechos a medida, por lo que son eficientes y rápidos en su
ejecución y gestión, pero por lo mismo carecen de flexibilidad para soportar
diferentes ambientes de trabajo o tipos de aplicaciones.
Estructura jerárquica.
A medida que fueron creciendo las necesidades de los usuarios y se
perfeccionaron los sistemas, se hizo necesaria una mayor organización del
software, del sistema operativo, donde una parte del sistema contenía subpartes
y esto organizado en forma de niveles. Se dividió el sistema operativo en
pequeñas partes, de tal forma que cada una de ellas estuviera perfectamente
definida y con un claro interface con el resto de elementos. Se constituyó una
estructura jerárquica o de niveles en los sistemas operativos, el primero de los
cuales fue denominado THE (Technische Hogeschool, Eindhoven), de Dijkstra,
que se utilizó con fines didácticos (Ver Fig. 3). Se puede pensar también en
estos sistemas como si fueran `multicapa’. Multics y Unix caen en esa categoría.
[Feld93].
En la estructura anterior se basan prácticamente la mayoría de los sistemas
operativos actuales. Otra forma de ver este tipo de sistema es la denominada de
anillos concéntricos o “rings”.
En el sistema de anillos, cada uno tiene una apertura, conocida como puerta o
trampa (trap), por donde pueden entrar las llamadas de las capas inferiores. De
esta forma, las zonas más internas del sistema operativo o núcleo del sistema
estarán más protegidas de accesos indeseados desde las capas más externas.
Las capas más internas serán, por tanto, más privilegiadas que las externas.
Máquina Virtual. Se trata de un tipo de sistemas operativos que presentan una
interface a cada proceso, mostrando una máquina que parece idéntica a la
máquina real subyacente. Estos sistemas operativos separan dos conceptos que
suelen estar unidos en el resto de sistemas: la multiprogramación y la máquina
extendida. El objetivo de los sistemas operativos de máquina virtual es el de
integrar distintos sistemas operativos dando la sensación de ser varias máquinas
diferentes. El núcleo de estos sistemas operativos se denomina monitor virtual y
tiene como misión llevar a cabo la multiprogramación, presentando a los niveles
superiores tantas máquinas virtuales como se soliciten. Estas máquinas virtuales
no son máquinas extendidas, sino una réplica de la máquina real, de manera
que en cada una de ellas se pueda ejecutar un sistema operativo diferente, que
será el que ofrezca la máquina extendida al usuario (Ver Fig. 5).
Cliente-servidor ( Microkernel) El tipo más reciente de sistemas operativos es
el denominado Cliente-servidor, que puede ser ejecutado en la mayoría de las
computadoras, ya sean grandes o pequeñas. Este sistema sirve para toda clase
de aplicaciones por tanto, es de propósito general y cumple con las mismas
actividades que los sistemas operativos convencionales. El núcleo tiene como
misión establecer la comunicación entre los clientes y los servidores. Los
procesos pueden ser tanto servidores como clientes. Por ejemplo, un programa
de aplicación normal es un cliente que llama al servidor correspondiente para
acceder a un archivo o realizar una operación de entrada/salida sobre un
dispositivo concreto. A su vez, un proceso cliente puede actuar como servidor
para otro.” [Alcal92]. Este paradigma ofrece gran flexibilidad en cuanto a los
servicios posibles en el sistema final, ya que el núcleo provee solamente
funciones muy básicas de memoria, entrada/salida, archivos y procesos,
dejando a los servidores proveer la mayoría que el usuario final o programador
puede usar. Estos servidores deben tener mecanismos de seguridad y
protección que, a su vez, serán filtrados por el núcleo que controla el hardware.
Actualmente se está trabajando en una versión de UNIX que contempla en su
diseño este paradigma. 2.2 Sistemas Operativos por Servicios Esta clasificación
es la más comúnmente usada y conocida desde el punto de vista del usuario
final. Esta clasificación se comprende fácilmente con el cuadro sinóptico que a
continuación se muestra en la Fig. 6.
Monousuario. Los sistemas operativos monousuarios son aquéllos que
soportan a un usuario a la vez, sin importar el número de procesadores que
tenga la computadora o el número de procesos o tareas que el usuario pueda
ejecutar en un mismo instante de tiempo. Las computadoras personales
típicamente se han clasificado en este renglón.
Multiusuario Los sistemas operativos multiusuarios son capaces de dar servicio
a más de un usuario a la vez, ya sea por medio de varias terminales conectadas
a la computadora o por medio de sesiones remotas en una red de
comunicaciones. No importa el número de procesadores en la máquina ni el
número de procesos que cada usuario puede ejecutar simultáneamente.
Monotareas Los sistemas monotarea son aquellos que sólo permiten una tarea
a la vez por usuario. Puede darse el caso de un sistema multiusuario y
monotarea, en el cual se admiten varios usuarios al mismo tiempo pero cada
uno de ellos puede estar haciendo solo una tarea a la vez.
Multitareas Un sistema operativo multitarea es aquél que le permite al usuario
estar realizando varias labores al mismo tiempo. Por ejemplo, puede estar
editando el código fuente de un programa durante su depuración mientras
compila otro programa, a la vez que está recibiendo correo electrónico en un
proceso en background. Es común encontrar en ellos interfaces gráficas
orientadas al uso de menús y el ratón, lo cual permite un rápido intercambio
entre las tareas para el usuario, mejorando su productividad.
Uniproceso Un sistema operativo uniproceso es aquél que es capaz de
manejar solamente un procesador de la computadora, de manera que si la
computadora tuviese más de uno le sería inútil. El ejemplo más típico de este
tipo de sistemas es el DOS y MacOS?.
Multiproceso Un sistema operativo multiproceso se refiere al número de
procesadores del sistema, que es más de uno y éste es capaz de usarlos todos
para distribuir su carga de trabajo. Generalmente estos sistemas trabajan de dos
formas: simétrica o asimétricamente. Cuando se trabaja de manera asimétrica,
el sistema operativo selecciona a uno de los procesadores el cual jugará el papel
de procesador maestro y servirá como pivote para distribuir la carga a los demás
procesadores, que reciben el nombre de esclavos. Cuando se trabaja de manera
simétrica, los procesos o partes de ellos (threads) son enviados indistintamente
a cualesquira de los procesadores disponibles, teniendo, teóricamente, una
mejor distribución y equilibrio en la carga de trabajo bajo este esquema. Se dice
que un thread es la parte activa en memoria y corriendo de un proceso, lo cual
puede consistir de un área de memoria, un conjunto de registros con valores
específicos, la pila y otros valores de contexto. Us aspecto importante a
considerar en estos sistemas es la forma de crear aplicaciones para aprovechar
los varios procesadores. Existen aplicaciones que fueron hechas para correr en
sistemas monoproceso que no toman ninguna ventaja a menos que el sistema
operativo o el compilador detecte secciones de código paralelizable, los cuales
son ejecutados al mismo tiempo en procesadores diferentes. Por otro lado, el
programador puede modificar sus algoritmos y aprovechar por sí mismo esta
facilidad, pero esta última opción las más de las veces es costosa en horas
hombre y muy tediosa, obligando al programador a ocupar tanto o más tiempo a
la paralelización que a elaborar el algoritmo inicial.
Sistemas Operativos por la Forma de Ofrecer sus Servicios Esta
clasificación también se refiere a una visión externa, que en este caso se refiere
a la del usuario, el cómo accesa los servicios. Bajo esta clasificación se pueden
detectar dos tipos principales: sistemas operativos de red y sistemas operativos
distribuídos.
Sistemas Operativos de Red Los sistemas operativos de red se definen como
aquellos que tiene la capacidad de interactuar con sistemas operativos en otras
computadoras por medio de un medio de transmisión con el objeto de
intercambiar información, transferir archivos, ejecutar comandos remotos y un
sin fin de otras actividades. El punto crucial de estos sistemas es que el usuario
debe saber la sintaxis de un cinjunto de comandos o llamadas al sistema para
ejecutar estas operaciones, además de la ubicación de los recursos que desee
accesar. Por ejemplo, si un usuario en la computadora hidalgo necesita el
archivo matriz.pas que se localiza en el directorio /software/codigo en la
computadora morelos bajo el sistema operativo UNIX, dicho usuario podría
copiarlo a través de la red con los comandos siguientes: hidalgo% hidalgo% rcp
morelos:/software/codigo/matriz.pas . hidalgo% En este caso, el comando rcp
que significa “remote copy” trae el archivo indicado de la computadora morelos y
lo coloca en el directorio donde se ejecutó el mencionado comando. Lo
importante es hacer ver que el usuario puede accesar y compartir muchos
recursos.
Sistemas Operativos Distribuídos Los sistemas operativos distribuídos
abarcan los servicios de los de red, logrando integrar recursos ( impresoras,
unidades de respaldo, memoria, procesos, unidades centrales de proceso ) en
una sola máquina virtual que el usuario accesa en forma transparente. Es decir,
ahora el usuario ya no necesita saber la ubicación de los recursos, sino que los
conoce por nombre y simplementa los usa como si todos ellos fuesen locales a
su lugar de trabajo habitual. Todo lo anterior es el marco teórico de lo que se
desearía tener como sistema operativo distribuído, pero en la realidad no se ha
conseguido crear uno del todo, por la complejidad que suponen: distribuír los
procesos en las varias unidades de procesamiento, reintegrar sub-resultados,
resolver problemas de concurrencia y paralelismo, recuperarse de fallas de
algunos recursos distribuídos y consolidar la protección y seguridad entre los
diferentes componentes del sistema y los usuarios. [Tan92]. Los avances
tecnológicos en las redes de área local y la creación de microprocesadores de
32 y 64 bits lograron que computadoras mas o menos baratas tuvieran el
suficiente poder en forma autónoma para desafiar en cierto grado a los
mainframes, y a la vez se dio la posibilidad de intercomunicarlas, sugiriendo la
oportunidad de partir procesos muy pesados en cálculo en unidades más
pequeñas y distribuirlas en los varios microprocesadores para luego reunir los
sub-resultados, creando así una máquina virtual en la red que exceda en poder
a un mainframe. El sistema integrador de los microprocesadores que hacer ver a
las varias memorias, procesadores, y todos los demás recursos como una sola
entidad en forma transparente se le llama sistema operativo distribuído. Las
razones para crear o adoptar sistemas distribuídos se dan por dos razones
principales: por necesidad ( debido a que los problemas a resolver son
inherentemente distribuídos ) o porque se desea tener más confiabilidad y
disponibilidad de recursos. En el primer caso tenemos, por ejemplo, el control de
los cajeros automáticos en diferentes estados de la república. Ahí no es posible
ni eficiente mantener un control centralizado, es más, no existe capacidad de
cómputo y de entrada/salida para dar servicio a los millones de operaciones por
minuto. En el segundo caso, supóngase que se tienen en una gran empresa
varios grupos de trabajo, cada uno necesita almacenar grandes cantidades de
información en disco duro con una alta confiabilidad y disponibilidad. La solución
puede ser que para cada grupo de trabajo se asigne una partición de disco duro
en servidores diferentes, de manera que si uno de los servidores falla, no se
deje dar el servicio a todos, sino sólo a unos cuantos y, más aún, se podría tener
un sistema con discos en espejo ( mirror ) a través de la red,de manera que si un
servidor se cae, el servidor en espejo continúa trabajando y el usuario ni cuenta
se da de estas fallas, es decir, obtiene acceso a recursos en forma transparente.
Ventajas de los Sistemas Distribuídos En general, los sistemas distribuídos
(no solamente los sistemas operativos) exhiben algunas ventajas sobre los
sistemas centralizados que se describen enseguida. • Economía: El cociente
precio/desempeño de la suma del poder de los procesadores separados contra
el poder de uno solo centralizado es mejor cuando están distribuídos. •
Velocidad: Relacionado con el punto anterior, la velocidad sumada es muy
superior. • Confiabilidad: Si una sola máquina falla, el sistema total sigue
funcionando. • Crecimiento: El poder total del sistema puede irse incrementando
al añadir pequeños sistemas, lo cual es mucho más difícil en un sistema
centralizado y caro. • Distribución: Algunas aplicaciones requieren de por sí una
distribución física. Por otro lado, los sistemas distribuídos también exhiben
algunas ventajas sobre sistemas aislados. Estas ventajas son: • Compartir datos:
Un sistema distribuído permite compartir datos más fácilmente que los sistemas
aislados, que tendrian que duplicarlos en cada nodo para lograrlo. • Compartir
dispositivos: Un sistema distribuído permite accesar dispositivos desde cualquier
nodo en forma transparente, lo cual es imposible con los sistemas aislados. El
sistema distribuído logra un efecto sinergético. • Comunicaciones: La
comunicación persona a persona es factible en los sistemas distribuídos, en los
sistemas aislados no. _ Flexibilidad: La distribución de las cargas de trabajo es
factible en el sistema distribuídos, se puede incrementar el poder de cómputo.
Desventajas de los Sistemas Distribuídos Así como los sistemas distribuídos
exhiben grandes ventajas, también se pueden identificar algunas desventajas,
algunas de ellas tan serias que han frenado la producción comercial de sistemas
operativos en la actualidad. El problema más importante en la creación de
sistemas distribuídos es el software: los problemas de compartición de datos y
recursos es tan complejo que los mecanismos de solución generan mucha
sobrecarga al sistema haciéndolo ineficiente. El checar, por ejemplo, quiénes
tienen acceso a algunos recursos y quiénes no, el aplicar los mecanismos de
protección y registro de permisos consume demasiados recursos. En general,
las soluciones presentes para estos problemas están aún en pañales. Otros
problemas de los sistemas operativos distribuídos surgen debido a la
concurrencia y al paralelismo. Tradicionalmente las aplicaiones son creadas
para computadoras que ejecutan secuencialmente, de manera que el identificar
secciones de código `paralelizable’ es un trabajo ardúo, pero necesario para
dividir un proceso grande en sub-procesos y enviarlos a diferentes unidades de
procesamiento para lograr la distribución. Con la concurrencia se deben
implantar mecanismos para evitar las condiciones de competencia, las
postergaciones indefinidas, el ocupar un recurso y estar esperando otro, las
condiciones de espera circulares y , finalmente, los “abrazos mortales”
(deadlocks). Estos problemas de por sí se presentan en los sistemas operativos
multiusuarios o multitareas, y su tratamiento en los sistemas distribuídos es aún
más complejo, y por lo tanto, necesitará de algoritmos más complejos con la
inherente sobrecarga esperada.
Por otro lado, en el tema de sistemas distribuídos existen varios conceptos
importantes referentes al hadware que no se ven en este trabajo:
multicomputadoras, multiprocesadores, sistemas acoplados débil y fuertemente,
etc. En [Tan92] páginas 366 - 376 puede encontrarse material relacionado a
estos conceptos.
1.4 Estructuras de Sistemas Operativos
1.4.1 Sistemas monolíticos
Este tipo de organización es, con diferencia, la más común. El sistema operativo
se escribe como una colección de procedimientos, cada uno de los cuales puede
llamar a los demás cada vez que así lo requiera. Cuando se usa esta técnica,
cada procedimiento del sistema tiene una interfaz bien definida en términos de
parámetros y resultados, y cada uno de ellos es libre de llamar a cualquier otro,
si éste último proporciona un cálculo útil para el primero.
Para construir el programa objeto real del sistema operativo siguiendo este
punto de vista, se compilan de forma individual los procedimientos, o los ficheros
que contienen los procedimientos, y después se enlazan en un sólo fichero
objeto con el enlazador. En términos de ocultación de la información, ésta es
prácticamente nula: cada procedimiento es visible a los demás (en contraste con
una estructura con módulos o paquetes, en la que la mayoría de la información
es local a un módulo, y donde sólo los datos señalados de forma expresa
pueden ser llamados desde el exterior del módulo).
Los servicios (mediante llamadas al sistema) que proporciona el sistema
operativo se solicitan colocando los parámetros en lugares bien definidos, como
los registros o la pila, para después ejecutar una instrucción especial de trampa,
a veces referida como llamada al núcleo o llamada al supervisor. Esta
instrucción cambia la máquina del modo usuario al modo núcleo (también
conocido como modo supervisor), y transfiere el control al sistema operativo, lo
que se muestra en el evento (1) de la figura 5.1.
El sistema operativo examina entonces los parámetros de la llamada para
determinar cual de ellas se desea realizar, como se muestra en (2) de la figura
5.1. A continuación, el sistema operativo analiza una tabla que contiene en la
entrada k un apuntador al procedimiento que implementa la k-ésima llamada al
sistema. Esta operación, que se muestra en (3) de la figura 5.1, identifica el
procedimiento de servicio, al cual se llama. Por último, la llamada al sistema
termina y el control vuelve al programa del usuario.
Esta organización sugiere una estructura básica del sistema operativo:
Un programa principal que llama al procedimiento del servicio solicitado.
Un conjunto de procedimientos de servicio que lleva a cabo las llamadas al
sistema.
Un conjunto de procedimientos de utilidades que ayudan a los procedimientos
de servicio.
En este modelo, para cada llamada al sistema existe un procedimiento de
servicio que se encarga de ella. Los procedimientos de utilidad hacen cosas
necesarias para varios procedimientos de servicio, como por ejemplo, buscar los
datos del programa del usuario. Esta división de los procedimientos en tres
capas se muestra en la figura 5.2.
1.4.2 Modelo cliente-servidor
Una tendencia de los sistema operativos modernos es la de trasladar el código a
capas superiores, y eliminar la mayor parte posible del sistema operativo para
mantener un núcleo mínimo. El punto de vista usual es el implantar la mayoría
de las funciones del sistema operativo como procesos de usuario. Para solicitar
un servicio, como la lectura de un bloque de cierto fichero, un proceso de
usuario (denominado en este caso proceso cliente) envía la solicitud a un
proceso servidor, que realiza el trabajo y devuelve la respuesta.
En este modelo, que se muestra en la figura 5.3, lo único que hace el núcleo es
controlar la comunicación entre los clientes y los servidores. Al separar el
sistema operativo en partes, cada una de ellas controla una faceta del sistema,
como el servicio a ficheros, servicio a procesos, servicio a terminales o servicio a
la memoria; cada parte es pequeña y controlable. Además, puesto que todos los
servidores se ejecutan como procesos en modo usuario, y no en modo núcleo,
no tienen acceso directo al hardware. En consecuencia, si hay un error en el
servidor de ficheros éste puede fallar, pero esto no afectará en general a toda la
máquina.
Otra de las ventajas del modelo cliente-servidor es su capacidad de adaptación
para su uso en sistemas distribuidos (véase la figura 5.4). Si un cliente se
comunica con un servidor mediante mensajes, el cliente no necesita saber si el
mensaje se gestiona de forma local, en su máquina, o si se envía por medio de
una red a un servidor en una máquina remota. En lo que respecta al cliente, lo
mismo ocurre en ambos casos: se envió una solicitud y se recibió una respuesta.
La idea anterior de un núcleo que sólo controla el transporte de mensajes de
clientes a servidores, y viceversa, no es totalmente real. Algunas funciones del
sistema operativo (como la introducción de órdenes en los registros físicos de
los controladores de E/S) son difíciles, si no es que imposible de realizar, a
partir de programas de usuario. Existen dos formas de afrontar este problema.
Una es hacer que algunos procesos de servidores críticos (por ejemplo, los
gestores de los dispositivos de E/S) se ejecuten en realidad en modo núcleo,
con acceso total al hardware, pero de forma que se comuniquen con los demás
procesos mediante el mecanismo normal de mensajes.
La otra forma es construir una cantidad mínima de mecanismos dentro del
núcleo, pero manteniendo las decisiones de política relativos a los usuarios
dentro del espacio de los usuarios. Por ejemplo, el núcleo podría reconocer que
cierto mensaje enviado a una dirección especial indica que se tome el contenido
de ese mensaje y se cargue en los registros del controlador de algún disco, para
iniciar la lectura del disco. En este ejemplo, el núcleo ni siquiera inspeccionaría
los bytes del mensaje para ver si son válidos o tienen algún sentido; sólo los
copiaría ciegamente en los registros del controlador del disco. Es evidente que
debe utilizarse cierto esquema para limitar tales mensajes sólo a los procesos
autorizados. La separación entre mecanismos y política es un concepto
importante, aparece una y otra vez en diversos contextos de los sistemas
operativos.
1.5 Analisis de So Comerciales (LINUX, UNÍX, Windows, MACH, OS/2, VAX,
MVS, etc.)
Unidad 2 Administración de procesos
2.1 Descripción y Control de Procesos Sistemas Operativos

En algunos sistemas operativos como en los de tiempo compartido, cada
programa que se ejecuta, por ejemplo mediante una orden de
EJECUTAR dada por el usuario, se trata como un proceso
independiente. Estos procesos generados por el O.S se denominan
IMPLÍCITOS. Una vez terminada la ejecución de los mismos, su
eliminación también la realiza el propio O.S. Asi mismo, el O.S
proporciona en tiempo real los servicios que son necesarios para que el
usuario pueda definir procesos de forma explicita. Los programa acceden
a estos servicios realizando LLAMADAS AL SISTEMA(SYSTEM CALL).
 Estas llamadas pueden aparecer incrustadas en el código de un
programa de usuario o del propio sistema, en cuyo caso, se asemejan a
llamadas a procedimientos o funciones que dan lugar a transferencias de
rutinas del O.S cuando se invocan en tiempo real. Las llamadas al
sistema se realizan tambien, pero de forma indirecta, cuando se dan
ordenes al O.S a través de un terminal(ó SHELL)la rutina de
monitorización del terminal( que es asu vez un proceso) se encarga de
transformar la ordenes en llamadas al sistema.
 De este modo, al comienzo de la ejecución del programa principal de un
usuario se inicia la ejecución de un proceso. A su vez el proceso podría
crear nuevos procesos. En este caso, el proceso que crea otro nuevo se
denomina proceso padre(parent process), y el proceso creado de
denomina proceso hijo(child process). Una vez creado un proceso hijo,
la ejecución de padre e hijo transcurre de manera concurrente. De esta
forma se puede crear una jerarquía arborescente de procesos, en la que
un padre puede tener varios hijos y estos pueden tener otros hijos, etc,
pero donde cada hijo sólo tiene un padre.
 [CAPTURADO POR R.EDER. W.J ITVH VHSA, TAB!!]
2.2 Definicion de Proceso Sistemas Operativos
Un proceso es una instancia de ejecución de un programa, caracterizado por su
contador de programa, su palabra de estado(Palabra que recoge en binario el
estado del entorno de programa, después de la ejecución de cada instrucción.),
sus registros ( pequeña memoria interna del microprocesador, formada
generalmente por biestables) del procesador, su segmento de texto, pila (zona
reservada de la memoria o registros hardware donde se almacena
temporalmente el estado o información de un programa, rutina, etc..) y datos,
etc.
2.3 Estados de Procesos Sistemas Operativos
Como se ha puesto de manifiesto, el proceso es un elemento dinámico que
puede pasar por diferentes estados a lo lo largo de su existencia. De forma
general, un proceso puede encontrarse en un instante determinado en uno de lo
siguientes estados:






Activo, Preparado, Bloqueado o suspendido, Nonato y Muerto.
La tarea activa es la que está ejecutándose en un instante dado.En el
caso de sistemas con un único procesador, sólo puede haber una tarea
en dicho estado en cada instante.
En el estado de preparado, se encuentran todas las tareas que están
listas para ejecutarse pero que esperan a que un/el procesador quede
libre(hay otros procesos más prioritarios en ejecución).
Las tareas que están a la espera de que se cumpla una condición y que
por lo tanto, no están preparadas para ejecutase, se dice que están en el
estado bloqueado o suspendido; alguno ejemplos de condición son:
que se termine una operación de E/S o que se reciba una señal de
sincronización.
Un proceso esta muerto cuando ha terminado su ejecución o bien el
sistema operativo a detectado un error fatal y lo ha transferido a dicho
estado. Tambien es posible que haya entrado él como resultado de un
fallo del propio sistema operativo(cuestión que desgraciadamente suele
ocurrir frecuentemente en algunos OS.
El estado de nonato indica que el programa realmente existe pero
todavía no es conocido por el OS.
2.4 Control de Procesos Sistemas Operativos
Procesos
Def: Un proceso es un programa en ejecución.
Estados de procesos
El estado de un proceso define su actividad actual. Durante su existencia, un
proceso pasa por una serie de estados discretos. Estos estados son se
muestran en el siguiente diagrama:
A continuación se describe cada uno de estos procesos:
Estado
Descripción
Nuevo
Se dice que un proceso está en estado de nuevo cuando apenas se
encuentra en proceso de crearse.
Listo
Un proceso está en estado de listo, cuando podría usar una UCP, si
hubiera una disponible.
En
Se dice que un proceso está estado de ejecución, si en ese
ejecución momento tiene esta ocupando la CPU.
Se dice que un proceso está en estado de bloqueado, si espera que
Bloqueado ocurra algo, como por ejemplo, la terminación de una E/S, para así
poder ponerse en marcha.
Terminado
Cuando un proceso se ha completado su ejecución pasa a ser un
proceso terminado.
Transiciones de estados:
Cuando un trabajo es admitido se crea un proceso equivalente, y es insertado en
la ultima parte de la cola de listos (ésta se tratara más adelante). Cuando un
proceso pasa de un estado a otro se dice que hace una transición de estado,
estas transiciones se describen a continuación.
Transición
Descripción
Admitido(Proceso):Nuevo Listo
Cuando un proceso se ha creado y se le es
permito para competir por la CPU.
Despacho(Proceso):Listo En
ejecución
La asignación de la CPU al primer proceso de
la lista de listos es llamado despacho y es
ejecutado por la entidad de sistema llamada
despachador. Mientras que el proceso tenga la
CPU se dice que esta en ejecución.
Tiempo excedido(Proceso):En
ejecución Listo
El S.O , cuando un proceso se le expira el
intervalo de tiempo asignado para estar en
ejecución (CUANTO), hace que este proceso
que se hallaba en estado de ejecución pase al
estado de listo y inmediatamente el
despachador hace que el primer proceso de la
lista pase a estado de ejecución.
Bloqueo(Proceso):En ejecución
Bloqueado
Si un proceso que se encuentra en estado de
ejecución inicia una operación de E/s antes
que termine su cuanto, el proceso
voluntariamente abandona la CPU, es decir, el
proceso se bloquea a sí mismo.
Despertar(Proceso):Bloqueo
Listo
La única transición posible en nuestro modelo
básico ocurre cuando acaba una operación de
E/S (o alguna otra causa por la que esté
esperando el proceso), y esta termina pasa a
el estado de listo.
Salir(Proceso):En ejecución
Terminado
Esta transición ocurre cuando el proceso se ha
terminado de ejecutarse, y pasa a un estado
de terminado.
Nota: Para prevenir que un proceso monopolice el sistema, el S.O ajusta un reloj
de interrupción del hardware para permitir al usuario ejecutar su proceso durante
un intervalo de tiempo especifico. Cuando este tiempo expira el reloj genera una
interrupción, haciendo que el S.O recupere el control.
Cuando hay demasiada carga en el sistema se puede hacer uso de suspensión
y reanudación por el S.O, para equilibrar la carga del sistema. Para la
reanudación y la suspensión será necesario anexar otros dos estado los cuales
son: suspendido listo y suspendido bloqueado, con las siguiente definición de
transiciones:
Suspende_ejecución(Proceso): En ejecución Suspendido listo
Suspende_bloqueado(Proceso): Bloqueado Suspendido bloqueado
Reanuada(Proceso): Suspendido listo Listo
Termino_E/S(Proceso): Suspendido bloqueado Suspendido listo
Bloque de control de proceso (PCB):
La manifestación de un proceso en un S.O es un bloque de control de proceso
(PCB), es decir cada proceso es representado por su PCB. El PCB es una
estructura de datos que contiene cierta información importante acerca del
proceso.
Esta información es:

Estado actual del proceso

Id único para proceso

Prioridad del proceso

Apuntadores para localizar la memoria del proceso

Apuntadores para asignar recursos

Area para preservar registros.
El PCB es un almacenamiento central de información que permite al S.O
localizar toda la información clave sobre el proceso.
Operaciones con procesos:

Crear un proceso

Destruir un proceso

Suspender un proceso

Reanudar un proceso

Cambiar la prioridad de un proceso

Bloquear un proceso

Despertar un proceso

Despachar un proceso
La creación de un proceso implica varias operaciones, incluyendo:

Dar nombre al proceso

Registrarlo en la lista de sistema de procesos conocidos

Determinar la prioridad inicial del proceso

Crear el PCB

Asignar recursos iniciales
Un proceso puede crear varios procesos nuevos, a través de una llamada al
sistema de “crear proceso”, durante el curso de ejecución. El proceso creador se
denomina proceso padre , y los nuevos procesos son los hijos de ese proceso.
Cada uno de estos procesos nuevos puede a su vez crear otros procesos,
formando un árbol de procesos.
Cuando un proceso crea un proceso nuevo, hay dos posibilidades en términos
de ejecución:

El padre sigue ejecutándose de forma concurrente con sus hijos.

El padre espera hasta que algunos de sus hijos, o todos, han terminado.
También hay dos posibilidades en términos del espacio de direcciones del nuevo
proceso:

El proceso hijo es un duplicado del proceso padre.

Se carga un programa en el proceso hijo.
La terminación de procesos
Un proceso acaba cuando termina de ejecutar su último enunciado y le pide al
S.O que lo elimine utilizando la llamada al sistema salir (exit). En este momento,
el proceso podría devolver datos(salidas) a su proceso padre (por medio de la
llamada al sistema esperar). El S.O liberará los recursos del proceso, incluidos
la memoria física y virtual, archivos abiertos y buffers de E/S.
Hay otras circunstancias por la que un proceso puede terminar, esta puede ser
por la llamada al sistema abortar.
Un padre podría terminar la ejecución de uno de sus hijos por diversas razones,
como:

El hijo ha excedido en la utilización de algunos de los recursos que se le
asignaron.

La tarea que se asignó al hijo ya no es necesaria.

El padre va a salir, y el sistema operativo no permite que un hijo continúe
si su padre termina.
Planificadores:
En un sistema por lotes cuando hay demasiados procesos de los que se pueden
inmediatamente ejecutarse se deben de colocar en spool en un dispositivo de
almacenamiento masivo (por lo regular un disco), y ahí esperar hasta que
puedan ser ejecutados.
Para la planificación se hace uso de los sig. planificadores de procesos:
Planificador a corto plazo (o planificador de trabajos): este escoge procesos que
estén el spool (en disco) y los carga en la memoria para que se ejecuten.
Planificador a largo plazo (o planificador de CPU): este escoge entre los
procesos que estén listos para ejecutarse, y asigna la CPU a uno de ellos.
El planificador a largo plazo se ejecuta con mayor frecuencia que el de largo
plazo y también controla el grado de multiprogramación (numero de procesos
que están en la MP).
Un proceso se describen como:

Proceso limitado por CPU, este ocupa su mayor tiempo para realizar
cálculos.

Proceso limitado por E/S, este dedica su mayor tiempo a realizar
operaciones de E/S.
En un sistema de tiempo se introduce un planificador más , el cual es:
Planificador a mediano plazo: este intercambia procesos a disco y luego
intercambia a la memoria, a este esquema se le denomina intercambio
(swapping). Esto puede ser necesario para mejorar la mezcla de procesos o
cuando un cambio en las necesidades de memoria ha distribuido la memoria
disponible entre demasiados procesos y es preciso liberar algo de memoria.
Comunicación entre procesos:
Hay dos formas en que se puede comunicar los procesos, los cuales son:

Por medio de un esquema de comunicación por memoria compartida
(Buffer)

Por medio de un mecanismo de comunicación entre procesos (IPC,
Interprocess comunication).
La IPC ofrece un mecanismo que permite a los procesos cumunicarse y
sincronizar sus acciones. La mejor forma de proveer la comunicación entre
procesos es mediante un sistema de mensajes.
La función de un sistema de mensaje es permitir a los procesos comunicarse
entre sí sin tener que recurrir a variables compartidas.
Un recurso IPC ofrece por los menos 2 operaciones:
enviar (mensaje) (send) y recibir (mesanje) (receive).
Sea P y Q dos procesos que requieren comunicarse deberán enviarse
mensajes; para ello debe existir un enlace de comunicación entre ellos. Este
enlace puede implementarse de diversas maneras.
Los métodos para implementar lógicamente un enlace y las operaciones de
enviar / recibir son:

Comunicación directa o indirecta

Uso de buffer automático o explícito

Envío por copia o envío por referencia

Mensajes de tamaño fijo o variables
Comunicación directa:
Aquí cada proceso que desee comunicarse debe nombrar explícitamente el
destinatario o el remitente de la comunicación. Este esquema se define las
primitivas de la sig. manera:
Enviar(P,mensaje): Enviar un mensaje al proceso P.
Recibir(Q. Mensaje): Recibir un mensaje del proceso Q.
Con las siguientes propiedades:

Se establece automáticamente el enlace entre cada par de procesos. Lo
procesos sólo necesitan conocer la identidad de otro para la
comunicación.

Solo hay un enlace entre cada par de procesos.

El enlace puede ser unidireccional o bidireccional.
Este esquema exhibe un simetría de direccionamiento; es decir, los procesos
tanto emisor como receptor necesitan nombrar al otro para comunicarse.
Otra variante de este esquema es utilizar asimetría de direccionamiento, con la
sig. primitivas:
Enviar(P,mensaje): enviar un mensaje al proceso P.
Recibir(Id,mensaje) : recibir un mensaje de cualquier proceso con el que hubo
comunicación.
Aquí sólo el emisor nombra al destinatario; el destinatario no ésta obligado a
nombrar al emisor.
Comunicación indirecta:
Aquí los mensajes se envían a, y se reciben de, buzones (también llamados
PUERTOS). Un buzón puede considerarse en lo abstracto como un objeto en el
que los procesos pueden colocar mensajes y del cual se pueden sacar
mensajes. Cada buzón tiene una identificación única. Aquí dos proceso se
pueden comunicarse sólo si comparten un buzón. Las primitivas se definen
como:
Enviar (A,mensaje): enviar un mensaje al buzón A.
Recibir (A,mensaje): recibir un mensaje del buzón A.
Un enlace de comunicación tiene las sig. propiedades:

Se establece un enlace entre un par de procesos sólo si tienen un buzón
compartido.

Un enlace puede estar asociado a más de dos procesos.

Entre cada par de procesos en comunicación puede haber varios enlaces
distintos, cada uno de los cuales corresponderá a un buzón.

Los enlaces pueden ser unidireccionales o bidereccionales.
Hay varias formas de designar el dueño de y los usuarios de un buzón dado.
Una posibilidad es permitir que un proceso declare variables de tipo buzón. El
proceso que declara un buzón es el dueño de ese buzón. Cualquier otro proceso
que conozca el nombre de dicho buzón podrá usarlo.
Por otro lado, un buzón propiedad del S.O tiene existencia propia; es
independiente y no está unido a ningún proceso específico. El S.O establece un
mecanismo que permite a un proceso:

Crear un buzón nuevo

Enviar y recibir mensajes a través del buzón

Destruir un buzón.
2.5 Procesos e Hilos
Tema en otro documento….
2.6Concurrencia Exclusión Mutua y Sincronización
Los temas fundamentales del diseño de sistemas operativos están relacionados
con la gestión de procesos e hilos:
• Multiprogramación: consiste en la gestión de varios procesos dentro de un
sistema mono-procesador.
• Multiprocesamiento: consiste en la gestión de varios procesos, dentro de un
sistema multiprocesador.
• Procesamiento distribuido: consiste en la gestión de varios procesos,
ejecutándose en sistemas de computadores múltiples y distribuidos. La reciente
proliferación de las agrupaciones es el principal ejemplo de este tipo de
sistemas.
La concurrencia es fundamental en todas estas áreas y para el diseño sistemas
operativos. La concurrencia comprende un gran número de cuestiones de
diseño, incluida la comunicación entre procesos, compartición y competencia por
los recursos, sincronización de la ejecución de varios procesos y asignación del
tiempo de procesador a los procesos. Se verá que estas cuestiones no solo
surgen en entornos de multiprocesadores y proceso distribuido, sino incluso en
sistemas multiprogramados con un solo procesador.
La concurrencia puede presentarse en tres contextos diferentes:
• Múltiples aplicaciones: la multiprogramación se creó para permitir que el tiempo
de procesador de la máquina fuese compartido dinámicamente entre varias
aplicaciones activas.
• Aplicaciones estructuradas: como ampliación de los principios del diseño
modular y la programación estructurada, algunas aplicaciones pueden
implementarse eficazmente como un conjunto de procesos concurrentes.
• Estructura del sistema operativo: las mismas ventajas de estructuración son
aplicables a los programadores de sistemas y se ha comprobado que algunos
sistemas operativos están implementados como un conjunto de procesos o hilos.
PRINCIPIOS GENERALES DE LA CONCURRENCIA
En un sistema multiprogramado con un único procesador, los procesos se
intercalan en el tiempo aparentando una ejecución simultánea. Aunque no se
logra un procesamiento paralelo y produce una sobrecarga en los intercambios
de procesos, la ejecución intercalada produce beneficios en la eficiencia del
procesamiento y en la estructuración de los programas.
La intercalación y la superposición pueden contemplarse como ejemplos de
procesamiento concurrente en un sistema monoprocesador, los problemas son
consecuencia de la velocidad de ejecución de los procesos que no pueden
predecirse y depende de las actividades de otros procesos, de la forma en que
el sistema operativo trata las interrupciones surgen las siguientes dificultades:
Compartir recursos globales es riesgoso Para el sistema operativo es difícil
gestionar la asignación óptima de recursos. Las dificultades anteriores también
se presentan en los sistemas multiprocesador.
El hecho de compartir recursos ocasiona problemas, por esto es necesario
proteger a dichos recursos.
Los problemas de concurrencia se producen incluso cuando hay un único
procesado
LABORES DEL SISTEMA OPERATIVO
Elementos de gestión y diseño que surgen por causa de la concurrencia:
1) El sistema operativo debe seguir a los distintos procesos activos
2) El sistema operativo debe asignar y retirar los distintos recursos a cada
proceso activo, entre estos se incluyen:
_Tiempo de procesador
_Memoria
_Archivos
_Dispositivos de E/S
3) El sistema operativo debe proteger los datos y los recursos físicos de cada
proceso contra injerencias no intencionadas de otros procesos.
4) Los resultados de un proceso deben ser independientes de la velocidad a la
que se realiza la ejecución de otros procesos concurrentes.
Para abordar la independencia de la velocidad debemos ver las formas en las
que los procesos interactúan.
INTERACCIÓN ENTRE PROCESOS
Se puede clasificar los en que interactúan los procesos en función del nivel de
conocimiento que cada proceso tiene de la existencia de los demás. Existen tres
niveles de conocimiento:
1) Los procesos no tienen conocimiento de los demás: son procesos
independientes que no operan juntos. Ej: la multiprogramación de procesos
independientes. Aunque los procesos no trabajen juntos, el sistema operativo se
encarga de la “competencia” por los recursos.
2) Los procesos tienen un conocimiento indirecto de los otros: los procesos no
conocen a los otros por sus identificadores de proceso, pero muestran
cooperación el objeto común.
3) Los procesos tienen conocimiento directo de los otros: los procesos se
comunican por el identificador de proceso y pueden trabajar conjuntamente.
Competencia entre procesos por los recursos
Los procesos concurrentes entran en conflicto cuando compiten por el uso del
mismo recurso; dos o más procesos necesitan acceder a un recurso durante su
ejecución .Cada proceso debe dejar tal y como esté el estado del recurso que
utilice.
La ejecución de un proceso puede influir en el comportamiento de los procesos
que compiten. Por Ej. Si dos procesos desean acceder a un recurso, el sistema
operativo le asignará el recurso a uno y el otro tendrá que esperar.
Cuando hay procesos en competencia, se deben solucionar tres problemas de
control: la necesidad de exclusión mutua. Suponiendo que dos procesos quieren
acceder a un recurso no compartible. A estos recursos se les llama “recursos
críticos” y la parte del programa que los utiliza es la “sección crítica” del
programa. Es importante que sólo un programa pueda acceder a su sección
crítica en un momento dado.
Hacer que se cumpla la exclusión mutua provoca un interbloqueo.
Otro problema es la inanición si tres procesos necesitan acceder a un recurso,
P1 posee al recurso, luego lo abandona y le concede el acceso al siguiente
proceso P2, P1 solicita acceso de nuevo y el sistema operativo concede el
acceso a P1 YP2 alternativamente, se puede negar indefinidamente a P3 el
acceso al recurso.
El control de competencia involucra al sistema operativo, porque es el que
asigna los recursos.
Cooperación entre procesos por compartimiento Comprende los procesos que
interactúan con otros sin tener conocimiento explícito de ellos. Ej. : Varios
procesos pueden tener acceso a variables compartidas.
Los procesos deben cooperar para asegurar que los datos que se comparten se
gestionan correctamente. Los mecanismos de control deben garantizar la
integridad de los datos compartidos.
Cooperación entre procesos por comunicación Los distintos procesos participan
en una labor común que une a todos los procesos.
La comunicación sincroniza o coordina las distintas actividades, está formada
por mensajes de algún tipo. Las primitivas para enviar y recibir mensajes, vienen
dadas como parte del lenguaje de programación o por el núcleo del sistema
operativo
REQUISITOS PARA LA EXCLUSIÓN MUTUA
Sólo un proceso, de todos los que poseen secciones críticas por el mismo
recurso compartido, debe tener permiso para entrar en ella en un momento
dado. Un proceso que se interrumpe en una sección no crítica debe hacerlo sin
interferir con los otros procesos. Un proceso no debe poder solicitar acceso a
una sección crítica para después ser demorado indefinidamente, no puede
permitirse el interbloqueo o la inanición. Si ningún proceso está en su sección
crítica, cualquier proceso que solicite entrar en la suya debe poder hacerlo sin
demora. No se debe suponer sobre la velocidad relativa de los procesos o el
número de procesadores. Un proceso permanece en su sección crítica por un
tiempo finito. Una manera de satisfacer los requisitos de exclusión mutua es
dejar la responsabilidad a los procesos que deseen ejecutar concurrentemente.
Tanto si son programas del sistema como de aplicación, los procesos deben
coordinarse unos con otros para cumplir la exclusión mutua, sin ayuda del
lenguaje de programación o del sistema operativo. Estos métodos se conocen
como soluciones por software.
EXCLUSIÓN MUTUA: SOLUCIONES POR SOFTWARE
Pueden implementarse soluciones de software para los procesos concurrentes
que se ejecuten en máquinas monoprocesador o multiprocesador con memoria
principal compartida.
ALGORITMO DE DEKKER
La solución se desarrolla por etapas. Este método ilustra la mayoría de los
errores habituales que se producen en la construcción de programas
concurrentes.
Primer intento
Cualquier intento de exclusión mutua debe depender de algunos mecanismos
básicos de exclusión en el hardware. El más habitual es que sólo se puede
acceder a una posición de memoria en cada instante, teniendo en cuenta esto
se reserva una posición de memoria global llamada turno. Un proceso que
desea ejecutar su sección crítica primero evalúa el contenido de turno. Si el valor
de turno es igual al número del proceso, el proceso puede continuar con su
sección crítica. En otro caso el proceso debe esperar. El proceso en espera, lee
repetitivamente el valor de turno hasta que puede entrar en su sección crítica.
Este procedimiento se llama espera activa.
Después de que un proceso accede a su sección crítica y termina con ella, debe
actualizar el valor de turno para el otro proceso.
Segundo intento:
Cada proceso debe tener su propia llave de la sección crítica para que, si uno de
ellos falla, pueda seguir accediendo a su sección crítica; para esto se define un
vector booleano señal. Cada proceso puede evaluar el valor de señal del otro,
pero no modificarlo. Cuando un proceso desea entrar en su sección crítica,
comprueba la variable señal del otro hasta que tiene el valor falso (indica que el
otro proceso no está en su sección crítica). Asigna a su propia señal el valor
cierto y entra en su sección crítica. Cuando deja su sección crítica asigna falso a
su señal.
Si uno de los procesos falla fuera de la sección crítica, incluso el código para dar
valor a las variables señal, el otro proceso no se queda bloqueado. El otro
proceso puede entrar en su sección crítica tantas veces como quiera, porque la
variable señal del otro proceso está siempre en falso. Pero si un proceso falla en
su sección crítica o después de haber asignado cierto a su señal, el otro proceso
estará bloqueado permanentemente.
Tercer intento
El segundo intento falla porque un proceso puede cambiar su estado después de
que el otro proceso lo ha comprobado pero antes de que pueda entrar en su
sección crítica.
Si un proceso falla dentro de su sección crítica, incluso el código que da valor a
la variable señal que controla el acceso a la sección crítica, el otro proceso se
bloquea y si un proceso falla fuera de su sección crítica, el otro proceso no se
bloquea.
Si ambos procesos ponen sus variables señal a cierto antes de que ambos
hayan ejecutado una sentencia, cada uno pensará que el otro ha entrado en su
sección crítica, generando así un interbloqueo.
Cuarto intento
En el tercer intento, un proceso fijaba su estado sin conocer el estado del otro.
Se puede arreglar esto haciendo que los procesos activen su señal para indicar
que desean entrar en la sección crítica pero deben estar listos para desactivar la
variable señal y ceder la preferencia al otro proceso.
Existe una situación llamada bloqueo vital, esto no es un interbloqueo, porque
cualquier cambio en la velocidad relativa de los procesos rompería este ciclo y
permitiría a uno entrar en la sección crítica. Recordando que el interbloqueo se
produce cuando un conjunto de procesos desean entrar en sus secciones
críticas, pero ninguno lo consigue. Con el bloqueo vital hay posibles secuencias
de ejecución con éxito.
Una solución correcta
Hay que observar el estado de ambos procesos, que está dado por la variable
señal, pero es necesario imponer orden en la actividad de los procesos para
evitar el problema de “cortesía mutua”. La variable turno del primer intento puede
usarse en esta labor, indicando que proceso tiene prioridad para exigir la entrada
a su sección crítica.
ALGORITMO DE PETERSON
El algoritmo de Deker resuelve el problema de la exclusión mutua pero mediante
un programa complejo, difícil de seguir y cuya corrección es difícil de demostrar.
Peterson ha desarrollado una solución simple y elegante. Como antes, la
variable global señal indica la posición de cada proceso con respecto a la
exclusión mutua y la variable global turno resuelve los conflictos de
simultaneidad.
Considérese el proceso P0. Una vez que ha puesto señal[0] a cierto, P1 no
puede entrar en su sección crítica. Si P1 esta aun en su sección crítica,
entonces señal[1] = cierto y P0 está bloqueado en su bucle while. Esto significa
que señal[1] es cierto y turno = 1. P0 puede entrar en su sección crítica cuando
señal[1] se ponga a falso o cuando turno se ponga a 0. Considérense ahora los
siguientes casos exhaustivos:
P1 no está interesado en entrar en su sección crítica. Este caso es imposible
porque implica que señal[1] = falso. P1 está esperando entrar en su sección
crítica. Este caso es también imposible porque si turno = 1, P1 podría entrar en
su sección crítica. P1 entra en su sección crítica varias veces y monopoliza el
acceso a ella. Esto no puede pasar porque P1 está obligado a dar a P0 una
oportunidad poniendo turno a 0 antes de cada intento de entrar en su sección
crítica. Así pues, se tiene una solución posible al problema de la exclusión mutua
para dos procesos. Es más, el algoritmo de Peterson se puede generalizar
fácilmente al caso de n procesos.
Disciplina de cola
La disciplina de cola mas simple es la de primero en llegar/ primero en salir, pero
ésta puede no ser suficiente si algunos mensajes son mas urgentes que otros.
Una alternativa es permitir la especificación de prioridades de los mensajes, en
función del tipo de mensaje o por designación del emisor. Otra alternativa es
permitir al receptor examinar la cola de mensajes y seleccionar el mensaje a
recibir a continuación.
Exclusión mutua
Supóngase que se usan primitivas receive bloqueantes y send no bloqueantes.
Un conjunto de procesos concurrentes comparten un buzón, exmut, que puede
ser usado por todos los procesos para enviar y recibir. El buzón contiene
inicialmente un único mensaje, de contenido nulo. Un proceso que desea entrar
en su sección crítica intenta primero recibir el mensaje. Si el buzón está vacío, el
proceso se bloquea. Una vez que un proceso ha conseguido el mensaje, ejecuta
su sección crítica y, después, devuelve el mensaje al buzón. De este modo, el
mensaje funciona como testigo que se pasa de un proceso a otro.
Esta técnica supone que si hay más de un proceso ejecutando la acción receive
concurrentemente, entonces:
Si hay un mensaje, se entrega sólo a uno de los procesos y los otros se
bloquean. Si el buzón está vacío, todos los procesos se bloquean; cuando haya
un mensaje disponible, sólo se activará y tomará el mensaje uno de los procesos
bloqueados.
EXCLUSIÓN MUTUA: SOLUCIONES POR HARDWARE
INHABILITACIÓN DE INTERRUPCIONES
En una máquina monoprocesador, la ejecución de procesos concurrentes no
puede superponerse; los procesos solo pueden intercalarse. Es más, un proceso
continuará ejecutándose hasta que solicite un servicio el sistema operativo o
hasta que sea interrumpido. Por lo tanto, para garantizar la exclusión mutua, es
suficiente con impedir que un proceso sea interrumpido. Esta capacidad puede
ofrecerse en forma de primitivas definidas por el núcleo del sistema para habilitar
o inhabilitar las interrupciones. Un proceso puede hacer cumplir la exclusión
mutua del siguiente modo:
While (cierto)
{
/*inhabilitar interrupciones */;
/* sección critica */;
/* habilitar interrupciones */;
/* resto */;
}
Puesto que la sección crítica no puede ser interrumpida, la exclusión mutua está
garantizada. Sin embargo, el precio de esta solución es alto. La eficiencia de la
ejecución puede verse notablemente degradada debido a que se limita la
capacidad del procesador para intercalar programas. Un segundo problema es
que está técnica no funciona en arquitecturas de multiprocesador. Cuando el
sistema tenga más de un procesador, es posible (y habitual) que haya más de
un proceso ejecutándose al mismo tiempo. En este caso, inhabilitar las
interrupciones no garantiza la exclusión mutua.
INSTRUCCIONES ESPECIALES DE MAQUINA
En configuraciones multiprocesador, varios procesadores comparten el acceso a
una memoria principal común. En este caso, no hay relación maestro/esclavo,
sino que los procesadores funcionan independientemente en una relación de
igualdad. No hay un mecanismo de interrupciones entre los procesadores en el
que se pueda basar la exclusión mutua.
A nivel de hardware, como se ha mencionado, los accesos a posiciones de
memoria excluyen cualquier otro acceso a la misma posición. Con esta base, los
diseñadores han propuesto varias instrucciones de máquina que realizan dos
acciones atómicamente, tales cono leer y escribir o leer y examinar, sobre una
misma posición de memoria en un único ciclo de lectura de instrucción.
Puesto que estas acciones se realizan en un único ciclo de instrucción, no están
sujetas a injerencias por parte de otras instrucciones.
-La instrucción COMPARAR Y FIJAR (TS, Test and Set)puede definirse de la
siguiente forma:
booleano TS(int i)
{
if (I==0)
{
I=1;
return cierto;
}
else
{
return falso;
}
}
La instrucción examina el valor de su argumento i. Si el valor es 0 , lo cambia por
1 y devuelve cierto. En otro caso, el valor no se modifica y se devuelve falso. La
función Comparar y Fijar se ejecuta atómicamente en su totalidad, es decir, no
esta sujeta a interrupciones.
La instrucción INTERCAMBIAR se puede definir como sigue:
void intercambiar (int registro, int memoria)
{
int temp;
temp = memoria;
memoria = registro;
registro = temp;
}
Esta instrucción intercambia el contenido de un registro con el de una posición
de memoria. Durante la ejecución de la instrucción, se bloquea el acceso a la
posición de memoria de cualquier otra instrucción que haga referencia a la
misma posición.
Propiedades de las soluciones con instrucciones de maquina
El uso de instrucciones especiales de la maquina para hacer cumplir la exclusión
mutua tiene varias ventajas:
Es aplicable a cualquier número de procesos en sistemas con memoria
compartida, tanto de monoprocesador como de multiprocesador. Es simple y
fácil de verificar. Puede usarse para disponer de varias secciones críticas; cada
sección crítica puede definirse con su propia variable. Algunas desventajas
importantes son las siguientes:
SE EMPLEA ESPERA ACTIVA. Así pues, mientras un proceso está esperando
para acceder a la sección crítica, continúa consumiendo tiempo del procesador.
PUEDE PRODUCIRSE INANICIÓN. Cuando un proceso abandona la sección
crítica y hay más de un proceso esperando, la selección es arbitraria. Así pues
se podría denegar el acceso a algún proceso indefinidamente. PUEDE
PRODUCIRSE INTERBLOQUEO. Supóngase la siguiente escena en un sistema
monoprocesador. El proceso “P1″ ejecuta una instrucción especial (sea TS o
Intercambiar) y entra su sección crítica. Se interrumpe a “P1″ para dar el
procesador a “P2″, que tiene mayor prioridad. Si “P2″ intenta ahora usar el
mismo recurso que “P1″, se le negará el acceso por el mecanismo de exclusión
mutua. De este modo, “P2″ entrará en un bucle de espera activa. Sin embargo,
“P1″ nunca será expedido porque su prioridad es menor que la del proceso listo
“p2″.
SEMÁFOROS
Para solucionar problemas de procesos concurentes, se diseño un S.O. como un
conjunto de procesos secuenciales, eficiente y fiables para dar soporte a la
cooperación. Los procesos de usuario podrían utilizar estos mecanismos si el
procesador y el S.O. los hacían disponible.
El principio fundamental es el siguiente, 20+ procesos pueden cooperar por
medio de simples señales, de manera que se pueda obligar a un proceso a
detener en una posición determinada hasta que reciba una señal específica.
Para la señalización se usan variables especiales llamadas semáforos “S”, los
procesos ejecutan las primitivas wait(s) si la señal aun no se transmitió, el
proceso se suspende hasta que tiene lugar la transmisión.
A los semáforos se los contemplan como variables que tienen un N° entero
sobre el que se definen las siguientes operaciones:
un semáforo puede iniciarse con un valor negativo la operación wait disminuye el
valor del semáforo. Si el valor no es positivo el proceso que ejecuta wait se
bloquea. las operaciones signal incrementa el N° del semáforo. Si el valor es
positivo se desbloquea el proceso bloqueado por una operación wait. No hay
forma de examinar o manipular los semáforos aparte de estas tres operaciones.
Las primitivas wait y signal se suponen atómicas, es decir no pueden ser
interrumpidas y cada rutina puede considerarse como un peso indivisible.
Un semáforo solo puede tomar los valores 0 y 1. Son más sencillos de implantar
y pueden demostrarse que tienen la misma potencia de expresión que los
semáforos generales.
En ambos semáforos se emplean una cola para mantener los procesos en
espera, la cuestión reside en el orden en que se retiran los procesos de la cola.
La política utilizada el la de FIFO; el proceso que estuvo bloqueado durante mas
tiempo se libera de la cola, se denomina semáforo robusto (incluye esta
estrategia). Un semáforo débil no especifica el orden en que se retiran los
procesos de la cola.
Los semáforos robustos garantizan la inexistencia de inanición en el algoritmo
de exclusión mutua, pero no así en los semáforos débiles, se supone que los
semáforos son siempre robustos ya que son los más adecuados y porque son
los tipos de semáforos que más incluyen los S.O.
Implementación de los semáforos. Como se menciono anteriormente es
impredecible que las operaciones wait y signal sean implementadas como
primitivas atómicas.
La esencia del problema del productor/consumidor, es la exclusion mutua: solo 1
proceso puede manipular un semáforo a la vez, en una operación wait o signal.
Se pueden utilizar cualquier esquema de software con los algoritmos de Dekker
o Peterson los que suponen una sobrecarga de procesos sustancial. Otra
alternativa es usar uno de los esquemas de soporte del hardware p/la exclusion
mutua..
En sistemas monoprocesador procesador, se pueden inhibir las interrupciones
durante una operación wait o signal.
MONITORES
Los monitores son estructuras de un lenguaje de programación que ofrecen una
funcionalidad equivalente a las de los semáforos pero son más fáciles de
controlar. El concepto de monitor fue definido por primera vez en [HOAR 74] . La
estructura de monitor se ha implementado en varios lenguajes de programación
como: Pascal concurrente, Modulo-2, Java, etc.
En concreto, para una lista enlazada se puede necesitar un cierre que bloquee
todas las listas enlazadas o bien un cierre por cada elemento de una lista.
Monitores con Señales: ( definición de Hoare )
Un monitor es un modulo de software que consta de uno o más procedimientos,
una secuencia de inicio y uno datos locales. Sus características son las
siguientes:
Solo los procedimientos del monitor acceden a variables de datos locales. Un
proceso entra en el monitor invocando a uno de sus procedimientos. En el
monitor solo un proceso puede ser ejecutado en un momento dado; cualquier
otro proceso quedara suspendido esperando la disponibilidad del monitor. Al ser
un proceso por vez, el monitor puede ofrecer un servicio de exclusión mutua
fácilmente. Así una estructura de datos puede protegerse situándola dentro de
un monitor.
Los monitores deben ofrecer herramientas de sincronización. Por ejemplo: si un
proceso llama a un monitor y una vez dentro de él el proceso queda suspendido
esperando alguna condición, hará falta un servicio que libere al monitor y lo deje
disponible para el siguiente proceso. Mas tarde cuando la condición se cumpla el
proceso suspendido podrá regresar al monitor y ejecutarse desde el momento
de la suspensión.
El monitor proporciona variables de condición que son accesibles solo desde
dentro del monitor.
Hay dos funciones para operar variables de condición:
cwait ©: suspende la ejecución del proceso que llama bajo la condición “c”. El
monitor está ahora disponible para otro proceso. csignal ©: retorna la ejecución
de un proceso suspendido después de un cwait, bajo la misma condición. Si hay
varios procesos elige uno de ellos. Si un proceso de monitor ejecuta un csignal y
no hay tareas esperando entonces el csignal de pierde.
Aunque un proceso puede entrar al monitor llamando a cualquiera de sus
procedimientos, se puede decir que el monitor tiene un solo punto de acceso,
custodiado para que solo un proceso este en el monitor en un instante dado. Si
existen otros procesos tratando de entrar al monitor, estos se colocan en una
cola de procesos suspendidos esperando la disponibilidad del monitor.
Un proceso dentro de un monitor puede suspenderse a sí mismo,
temporalmente, bajo la condición X ejecutando cwait(x), entonces se coloca en
una cola de procesos que esperan que cambie la condición X entonces ejecuta
un csignal(x) que avisa a la cola de condición correspondiente de que la
condición a cambiado.
En el código se puede apreciar la solución al problema de productor /
consumidor usando monitores:
El modulo monitor, buffers_acotado, controla el buffer para almacenar y retirar
caracteres. El monitor incluye dos variables de condición:
No-lleno es verdadero su hay lugar para agregar al menos un carácter.
No-vació es verdadero si hay al menos un carácter en el buffer.
Un productor solo puede agregar caracteres al buffer mediante el procedimiento
añadir del monitor; el productor no tiene acceso directo al buffer. El
procedimiento comprueba si hay espacio en el buffer, mediante la condición nolleno, si no lo hay el proceso queda suspendido y cualquier otro proceso
(consumidor o productor) puede entrar al monitor. Luego, cuando el buffer ya no
esta lleno, el proceso se retira de la cola y es reactivado. Luego de añadir un
carácter el proceso activa la condición no-vació.
La estructura misma del monitor garantiza la exclusión mutua (solo un proceso
por vez puede acceder al buffer). Sin embargo, el programador debe situar
correctamente las primitivas cwait( ) y csignal( ) en el monitor para evitar que los
procesos depositen elementos en un buffer lleno o los extraigan de uno vació.
Un proceso sale del monitor inmediatamente después de ejecutar csignal( ).
Si csignal( ) se ejecuta antes del final entonces ese proceso libera el monitor y
esta colocado en una lista de procesos suspendidos. Un nuevo proceso puede
entrar el monitor.
Si no hay procesos esperando en la condición X, la ejecución de csignal (x) no
tiene efecto.
Es posible cometer errores en la sincronización de los monitores, por ejemplo, si
se omite cualquiera de las funciones csignal() en el monitor buffer _ acotado los
procesos que entran en la cola de condición permanecen colgados
permanentemente. Sin embargo la ventaja de los monitores es que todas las
funciones de sincronización están incluidas dentro del monitor, lo que permite
una fácil detección y corrección de fallas de sincronización.
Monitores con Notificación y Difusión (definición de Lampson y Redell)
Son varios los inconvenientes que presenta la solución de Hoare:
-Si el proceso que ejecuta el csignal( ) no ha terminado en el monitor, se
necesitaran dos cambios de procesos adicionales: uno para suspender el
proceso y otro para reanudarlo.
-La planificación de procesos asociados con las señales debe ser muy fiable. Si
un proceso ejecuta un csignal ( ), el proceso de la cola de condición
correspondiente debe activarse de inmediato, antes de que ingrese otro proceso
del exterior o cambie la condición bajo la que se activó el proceso. Otro caso
seria que un proceso productor escribe un carácter en el buffer y falla antes de
dar la señal, entonces la cola de condición no-vacía se colgaría para siempre.
Lampson y Redell desarrollaron una definición de monitores para el lenguaje
MESA [Lamp 80]. La estructura de mesa reemplaza la primitiva csignal( ) por
cnotify( ). Cuando un proceso ejecuta cnotify(x) envía una notificación a la cola
de condición X, lo cual no significa que el proceso que esta ocupando el monitor
vaya a detenerse, simplemente el cnotify(x) avisa al proceso de la cola de
condición correspondiente de que será reanudado en un futuro cercano. Puesto
que esta no garantiza que un proceso exterior entre al monitor, el proceso debe
comprobar la condición nuevamente.
En el código, la sentencia IF se reemplaza por un bucle While, lo cual genera
una evaluación extra de la variable, pero sin embargo no hay cambios de
procesos extra.
Una modificación útil seria asociar un temporizador de guardia a cnotify( ) que
permitiría que un proceso que ha esperado durante el intervalo máximo sea
situado en estado de listo, independientemente de sí se ha notificado la
condición.
Con la norma de notificar a los procesos en lugar de reactivarlos, es posible
añadir una primitiva de difusión cbroadcast. La difusión provoca que todos los
procesos que están esperando por una condición se coloquen en el estado de
listo. Esto es útil cuando un proceso no sabe cuantos procesos deben
reactivarse.
El método Lampson/Redell es menos propenso a errores debido a que cada
procedimiento comprueba la condición luego de ser despertado, por medio de la
instrucción while, un proceso puede realizar una señal o una difusión
incorrectamente sin provocar un error en el programa que la recibe.
Además este modelo presta un método mas modular de construcción de
programas.
Hay dos niveles de condición que deben satisfacerse para los procesos
secuenciales cooperantes.
Estructura de datos consistentes: significa que el monitor hace cumplir la
exclusión mutua y concluye la operación de entrada o salida antes de permitir
cualquier otra operación sobre el buffer. La misma condición del nivel 1 y,
además disponer de suficiente memoria para que este proceso pueda completar
su solicitud de asignación. PASO DE MENSAJES
Son 2 los requisitos básicos que deben satisfacerse cuando los procesos
interactúan entre si.
Ellos son:
La sincronización La comunicación Los procesos tienen que sincronizarse para
cumplir la exclusión mutua, los procesos cooperantes pueden necesitar
intercambiar información.
El paso de mensajes es un método que permite que se realice ambas funciones.
Este método tiene la ventaja de que es de fácil implementación en sistemas
distribuidos y también es sistemas de multiprocesador y monoprocesador de
memoria compartida.
La funcionalidad real del paso de mensajes, generalmente, se da por medio de
un par de primitivas:
send(destino, mensaje)
receive(origen, mensaje)
Este es el conjunto mínimo de operaciones necesarias para que los procesos
puedan dedicarse al paso de mensajes.
SINCRONIZACION
La comunicación de un mensaje entre 2 procesos implica cierto nivel de
sincronización entre ambos. El receptor no puede recibir un mensaje hasta que
sea enviado por otro proceso. Además hace falta especificar que le sucede a un
proceso después de ejecutar una primitiva SEND o RECEIVE.
Considérese en primer lugar la primitiva send. Cuando se ejecuta una primitiva
send en un proceso, hay 2 posibilidades: o bien el proceso emisor se bloquea
hasta que recibe el mensaje o no se bloquea. Igualmente cuando un proceso
ejecuta una primitiva RECEIVE, existen 2 opciones:
1) Si previamente se ha enviado algún mensaje, este es recibido y continua la
ejecución.
2) Si no hay ningún mensaje esperando entonces:
a) el proceso se bloquea hasta que llega un mensaje o,
b) el proceso continúa ejecutando, abandonando el intento de recepción.
El emisor y el receptor pueden ser bloqueantes o no bloqueantes.
Existen 3 tipos de combinaciones pero un sistema solo implementa uno o dos.
I) Envío bloqueante, recepción bloqueante: tanto el emisor como el receptor se
bloquean hasta que llega el mensaje; esta técnica se conoce como rendezvous.
II) Envío no bloqueante, recepción bloqueante: aunque el emisor puede
continuar, el receptor se bloquea hasta que llega el mensaje solicitado. Es la
combinación más útil.
III) Envío no bloqueante, recepción no bloqueante: nadie debe esperar.
El send no bloqueante es la forma más natural para muchas tareas de
programación concurrente. Un posible riesgo del send no bloquente es que por
error puede llevar a una situación en la que el proceso genere mensajes
repetidamente.
Para el receive, la versión bloqueante es la mas natural para muchas tareas de
programación concurrente. En general, un proceso que solicita un mensaje
necesitara la información esperada antes de continuar.
DIRECCIONAMIENTO
Es necesario disponer de alguna forma de especificar en la primitiva send que
proceso va a recibir el mensaje. La mayoría de las implementaciones permiten a
los procesos receptores indicar el origen del mensaje que se va a recibir.
Los distintos esquemas para hacer referencia a los procesos en las primitivas
send y receive se encuadran dentro de 2 categorías:
1) Direccionamiento directo: la primitiva send incluye una identificación
específica del proceso de destino.
La primitiva receive se puede gestionar de 2 formas:
Una posibilidad requiere que el proceso designe explícitamente un proceso
emisor. El proceso debe conocer de antemano de que proceso espera un
mensaje. En otros casos es imposible especificar el proceso de origen por
anticipado. 2) Direccionamiento indirecto: los mensajes no se envían
directamente del emisor al receptor, sino a una estructura de datos compartidos
formada por colas, que pueden guardar los mensajes temporalmente, que se
denominan BUZONES (mailboxes). Para que 2 procesos se comuniquen, uno
envía mensajes al buzón apropiado y el otro los retira. Una ventaja de este tipo
de direccionamiento es que se desacopla a emisor y receptor, asegurando
mayor flexibilidad en el uso de mensajes.
Relación entre emisores y receptores
UNO A UNO: permite que se establezca un enlace privado entre 2 procesos.
Aísla su interacción de injerencias erróneas de otros procesos. MUCHOS A
UNO: resulta útil para interacciones cliente-servidor. En este caso el buzón se
llama puerto. UNO A MUCHOS: permite un emisor y varios receptores. La
asociación de procesos a buzones puede ser ESTATICA o DINAMICA. Los
puertos suelen estar asociados estáticamente con algún proceso en particular.
El puerto se crea y se asigna al proceso permanentemente. Una relación de
UNO A UNO se define de forma estática y permanentemente. Cuando hay
varios emisores, la asociación a un BUZON puede realizarse dinámicamente. Se
pueden utilizar primitivas como CONECTAR o DESCONECTAR.
Propiedad del buzón. en el caso de 1 puerto, normalmente pertenece y se crea
por el RECPTOR. Entonces cuando se destruye el proceso, también se destruye
el puerto.
Para los buzones en general el S.O. ofrece un servicio de creación de buzones.
Son considerados como propiedad del proceso creador en cuyo caso se
destruyen junto con el proceso, o como propiedad del S.O., en este caso se
necesita una orden explicita para destruir el buzón.
FORMATO DE MENSAJES
Para algunos S.O. los diseñadores han elegido mensajes cortos y tamaños fijos
para minimizar procesamiento y coste de almacenamiento. Si se van a pasar
una gran cantidad de datos, estos pueden ponerse en un archivo y el mensaje
simplemente hará referencia a este archivo. Una solución más flexible es utilizar
mensajes de longitud variable.
DISCIPLINA DE COLA
La disciplina de cola más simple es FIFO, pero esta puede no ser suficiente para
mensajes más urgentes que otros. Una opción es habilitar la especificación de
prioridades de los mensajes, en función del tipo de mensajes o por designación
del emisor. Otra es permitir al receptor examinar la cola de mensajes y
seleccionar el mensaje a recibir a continuación.
EXCLUSION MUTUA
Con el siguiente algoritmo de muestra una forma de usar el PASO DE
MENSAJES para cumplir la exclusión mutua.
Se usan RECEIVE bloqueantes y SEND no bloqueantes. Unos procesos
concurrentes comparte un BUZON, EXMUT, que puede ser usado por todos los
procesos. EXMUT (buzón) tiene inicialmente un único mensaje nulo. Un proceso
que requiere entrar en su sección crítica intenta:
1) recibir el mensaje. Si el EXMUT(buzón) esta vacío, se bloquea el proceso.
2) Una vez que consiguió el mensaje, ejecuta su sección crítica y devuelve el
mensaje al buzón.
El mensaje funciona como un testigo(TOKEN) que se pasa de proceso a otro.
Esta técnica supone que si hay más de un proceso ejecutando la acción
RECEIVE concurrentemente, entonces:
Si hay un mensaje, se entrega solo a uno de los procesos y los demás se
bloquean. Si el buzón esta vacío, todos se bloquean cuando hay un mensaje,
solo se activara y tomara el mensaje uno de los procesos bloqueados.
PROBLEMA DE LOS LECTORES/ESCRITORES
Descripción del problema:
Existe un área de datos compartida entre una serie de procesos, algunos sólo
leen los datos (lectores) y otros sólo escriben datos (escritores). El problema es
satisfacer las siguientes condiciones:
1. Cualquier número de lectores puede leer el archivo simultáneamente.
2. En el archivo sólo puede escribir un escritor en cada instante.
3. Si un escritor está accediendo al archivo, ningún lector puede leerlo.
El problema general de exclusión mutua, consiste en permitir a cualquiera de los
procesos (lectores o escritores) leer o escribir en el área de datos. Esto hace
necesario declarar cualquier acceso como una sección crítica donde los
procesos tendrían que acceder uno a uno produciéndose intolerables retrasos,
además se debe impedir que los escritores interfieran unos con otros y también
que se realicen consultas mientras se llevan a cabo modificaciones
Aplicar la solución general al problema de los lectores/escritores sería
inaceptablemente lenta. En este caso más restrictivo es posible crear soluciones
más eficientes.
A continuación se examinan dos soluciones al problema:
PRIORIDAD A LOS LECTORES Es una solución que utiliza semáforos para
respetar la exclusión mutua. Se permite el acceso a varios lectores, pero
mientras que un escritor está accediendo a los datos compartidos, no se permite
acceder a ningún escritor o lector.
El primer lector que intenta acceder debe esperar en el semáforo, Cuando haya
al menos un lector, los lectores siguientes no necesitan esperar para entrar, se
les da prioridad. El problema es que un escritor estará esperando mientras que
haya al menos un lector leyendo, que luego podría dar paso a otro lector, en
este caso el lector estará sujeto a inanición.
Se utiliza una variable global contlect para mantener el número de lectores y el
semáforo x para que la actualización de contlect sea consistente. El semáforo
esem controla el acceso al recurso compartido.
/* program lectores_escntores*/
int contlect;
semáforo x = 1, esem=1;
void lector()
{
while (cierto)
{
wait(x);
contlect++;
If (contlect==1)
wait(esem);
signal(x);
LEER_UNIDAD();
wait(x);
contlect—;
If (contlect==0)
signal(esem);
signal(x);
}
}
void escritor()
{
while (cierto)
{
wait(esem);
ESCRIBIR_UNIDAD();
signal(esem);
}
}
vold main() {
contlect = 0;
parbegln(tector, escritor);
}
Una solución al problema de los lectores/escritores por medio de semáforos; los
lectores tienen prioridad.
2. PRIORIDAD A LOS ESCRITORES
Esta solución garantiza que no se permitirá acceder a los datos a ningún nuevo
lector una vez que, al menos, un escritor haya declarado su deseo de escribir.
Se utilizan los mismos semáforos que en la solución anterior y se añaden otros
más:
• Un semáforo Isem que inhibe todas las lecturas cuando al menos un escritor
desea acceder
• Una variable contesc que controla la activación de Isem
• Un semáforo y que controla la actualización de contesc
• Un semáforo y que controla la actualización de contesc
• Un semáforo z donde se encolan los lectores cuando ya hay uno en lsem
/* program lectores_escritores */
Int contlec, contesc;
semáforo x=1, y =1, z=1, esem=1, lsem=1;
void lector()
{
while (cierto)
{
wait(z);
wait(lsem);
wait(x);
contlect++;
if (contlect = = 1)
{
wait(esem);
}
signal(x);
signal(lsem);
signal(z);
LEER_UNIDAD();
wait(x);
contlect—;
if (contlect == 0)
signal(esem);
signal(x);
}
}
void escritor()
{
while (cierto)
{
wait(y);
contesc++;
if (contesc = = 1)
wait(lsem) ;
signal(y);
wait(esem);
ESCRIBIR_UNIDAD();
signal(esem);
wait(y);
contesc—;
If (contesc== 0)
signal(lsem);
signal(y);
}
}
void mailn()
{
contlect = contesc = 0;
parbegin (lector, escritor);
}
2.7 Principios Generales de Concurrencia
En un sistema multiprogramado con un único procesador, los procesos se
intercalan en el tiempo aparentando una ejecución simultánea. Aunque no se
logra un procesamiento paralelo y produce una sobrecarga en los intercambios
de procesos, la ejecución intercalada produce beneficios en la eficiencia del
procesamiento y en la estructuración de los programas. La intercalación y la
superposición pueden contemplarse como ejemplos de procesamiento
concurrente en un sistema monoprocesador, los problemas son consecuencia
de la velocidad de ejecución de los procesos que no pueden predecirse y
depende de las actividades de otros procesos, de la forma en que el sistema
operativo trata las interrupciones surgen las siguientes dificultades:
1. Compartir recursos globales es riesgoso
2. Para el sistema operativo es difícil gestionar la asignación óptima de recursos.
2.8 Exclusión Mutua : solución por hardware y software
Los algoritmos de exclusión mutua (comúnmente abreviada como mutex por
mutual exclusion) se usan en programación concurrente para evitar que
fragmentos de código conocidos como secciones críticas accedan al mismo
tiempo a recursos que no deben ser compartidos.
La mayor parte de estos recursos son las señales, contadores, colas y otros
datos que se emplean en la comunicación entre el código que se ejecuta cuando
se da servicio a una interrupción y el código que se ejecuta el resto del tiempo.
Se trata de un problema de vital importancia porque, si no se toman las
precauciones debidas, una interrupción puede ocurrir entre dos instrucciones
cualesquiera del código normal y esto puede provocar graves fallos.
La técnica que se emplea por lo común para conseguir la exclusión mutua es
inhabilitar las interrupciones durante el conjunto de instrucciones más pequeño
que impedirá la corrupción de la estructura compartida (la sección crítica). Esto
impide que el código de la interrupción se ejecute en mitad de la sección crítica.
En un sistema multiprocesador de memoria compartida, se usa la operación
indivisible test-and-set sobre una bandera, para esperar hasta que el otro
procesador la despeje. La operación test-and-set realiza ambas operaciones sin
liberar el bus de memoria a otro procesador. Así, cuando el código deja la
sección crítica, se despeja la bandera. Esto se conoce como spin lock o espera
activa.
Algunos sistemas tienen instrucciones multioperación indivisibles similares a las
anteriormente descritas para manipular las listas enlazadas que se utilizan para
las colas de eventos y otras estructuras de datos que los sistemas operativos
usan comúnmente.
La mayoría de los métodos de exclusión mutua clásicos intentan reducir la
latencia y espera activa mediante las colas y cambios de contexto. Algunos
investigadores afirman que las pruebas indican que estos algoritmos especiales
pierden más tiempo del que ahorran.
A pesar de todo lo dicho, muchas técnicas de exclusión mutua tienen efectos
colaterales. Por ejemplo, los semáforos permiten interbloqueos (deadlocks) en
los que un proceso obtiene un semáforo, otro proceso obtiene el semáforo y
ambos se quedan a la espera de que el otro proceso libere el semáforo. Otros
efectos comunes incluyen la inanición, en el cual un proceso esencial no se
ejecuta durante el tiempo deseado, y la inversión de prioridades, en el que una
tarea de prioridad elevada espera por otra tarea de menor prioridad, así como la
latencia alta en la que la respuesta a las interrupciones no es inmediata.
La mayor parte de la investigación actual en este campo, pretende eliminar los
efectos anteriormente descritos. Si bien no hay un esquema perfecto conocido,
hay un interesante esquema no clásico de envío de mensajes entre fragmentos
de código que, aunque permite inversiones de prioridad y produce una mayor
latencia, impide los interbloqueos.
Algunos ejemplos de algoritmos clásicos de exclusión mutua son:
El algoritmo de Dekker es un algoritmo de programación concurrente para
exclusión mutua, que permite a dos procesos o hilos de ejecución compartir un
recurso sin conflictos. Fue uno de los primeros algoritmos de exclusión mutua
inventados, implementado por Edsger Dijkstra.
Si ambos procesos intentan acceder a la sección crítica simultáneamente, el
algoritmo elige un proceso según una variable turno. Si el otro proceso está
ejecutando en su sección crítica, deberá esperar su finalización.
Existen 5 versiones del algoritmo Dekker, teniendo ciertos fallos los primeros
cuatro. La versión 5 es la que trabaja más eficientemente, siendo una
combinación de la 1 y la 4.
Versión 1: Alternancia Estricta.
Garantiza la exclusión mutua, pero su desventaja es que acopla los procesos
fuertemente, esto significa que los procesos lentos atrasan a los procesos
rápidos.
Versión 2: Problema interbloqueo.
No existe la alternancia, aunque ambos procesos caen a un mismo estado y
nunca salen de ahí.
Versión 3: Colisión región critica no garantiza la exclusión mutua.
Este algoritmo no evita que dos procesos puedan acceder al mismo tiempo a la
región critica.
Versión 4: Postergación indefinida.
Aunque los procesos no están en interbloqueo, un proceso o varios se quedan
esperando a que suceda un evento que tal vez nunca suceda.
shared int cierto = 1;
''/* Definición de variables compartidas */ ''
shared int bandera[2] = {0,0};
shared int turno
= 0;
while (cierto)
{
bandera[proc_id] = cierto;
while (bandera[1-proc_id] == cierto)
{
if (turno == 1-proc_id)
{
bandera[proc_id] = 0;
while (turno == (1-proc_id))
su turno de intentar */;
bandera[proc_id] = 1;
}
/* ''Sección crítica'' */
turno = 1-proc_id;
otro proceso */
bandera[proc_id] = 0;
/* ''Sección no crítica'' */
}
}
/* espera a que sea
/* es el turno del
Algoritmo de Peterson
El algoritmo de Peterson es un algoritmo de programación concurrente para
exclusión mutua, que permite a dos o más procesos o hilos de ejecución
compartir un recurso sin conflictos, utilizando sólo memoria compartida para la
comunicación.
Peterson desarrolló el primer algoritmo (1981) para dos procesos que fue una
simplificación del algoritmo de Dekker para dos procesos. Posteriormente este
algoritmo fue generalizado para que funcione para N procesos.
Algoritmo para dos procesos
bandera[0] = 0
bandera[1] = 0
turno
= 0
p0: bandera[0] = 1
turno = 1
while( bandera[1] && turno == 1 );
turno == 0 );
//no hace nada. espera.
//no hace nada. espera.
// sección crítica
// fin de la sección crítica
crítica
bandera[0] = 0
p1: bandera[1] = 1
turno = 0
while( bandera[0] &&
// sección crítica
// fin de la sección
bandera[1] = 0
2.9 Semaforos Sistemas Operativos
Semáforos es un algoritmo de control de procesos, que tiene solo dos
operaciones básicas, las cuales son:
Wait.- Pregunta a los procesos si su contador es > ó = que cero, en caso de no
ser así, los decrementa. El proceso que cambia en este caso a negativo (−1)
desde la cola de procesos Listos a ser ejecutados es el que automáticamente
toma el control del procesador.
Signal.- A partir de un tiempo t definido por el despachador se ejecuta, y
pregunta a los procesos si su contador es < que cero en caso de que sea
afirmativa la respuesta, saca a este proceso de su ejecución y depende de su
estado
2.10 Monitores Sistemas Operativos
Un monitor encapsula el código relativo a un recurso compartido en un solo
módulo de programa; ventajas:
• mantenimiento más simple
• menos errores de programación
La interfaz del monitor es un conjunto de funciones que representan las
diferentes operaciones que pueden hacerse con el recurso
La implementación del monitor garantiza la exclusión mutua
• mediante semáforos o algún otro mecanismo
• o implícitamente en los lenguajes concurrentes
2.11 Paso de Mensajes Sistemas Operativos
Paso de mensajes
El paso de mensajes es una técnica empleada en programación concurrente
para aportar sincronización entre procesos y permitir la exclusión mutua, de
manera similar a como se hace con los semáforos, monitores, etc.
Su principal característica es que no precisa de memoria compartida, por lo que
es muy importante en la programación para sistemas distribuidos.
Los elementos principales que intervienen en el paso de mensajes son el
proceso que envía, el que recibe y el mensaje.
2.12 Concurrencia e Interbloqueo deadlock
INTRODUCCIÓN
Los temas fundamentales del diseño de sistemas operativos están relacionados
con la gestión de procesos e hilos:
• Multiprogramación: consiste en la gestión de varios procesos dentro de un
sistema mono-procesador.
• Multiprocesamiento: consiste en la gestión de varios procesos, dentro de un
sistema multiprocesador.
• Procesamiento distribuido: consiste en la gestión de varios procesos,
ejecutándose en sistemas de computadores múltiples y distribuidos. La reciente
proliferación de las agrupaciones es el principal ejemplo de este tipo de
sistemas.
La concurrencia es fundamental en todas estas áreas y para el diseño sistemas
operativos. La concurrencia comprende un gran número de cuestiones de
diseño, incluida la comunicación entre procesos, compartición y competencia por
los recursos, sincronización de la ejecución de varios procesos y asignación del
tiempo de procesador a los procesos. Se verá que estas cuestiones no solo
surgen en entornos de multiprocesadores y proceso distribuido, sino incluso en
sistemas multiprogramados con un solo procesador.
La concurrencia puede presentarse en tres contextos diferentes:
• Múltiples aplicaciones: la multiprogramación se creó para permitir que el tiempo
de procesador de la máquina fuese compartido dinámicamente entre varias
aplicaciones activas.
• Aplicaciones estructuradas: como ampliación de los principios del diseño
modular y la programación estructurada, algunas aplicaciones pueden
implementarse eficazmente como un conjunto de procesos concurrentes.
• Estructura del sistema operativo: las mismas ventajas de estructuración son
aplicables a los programadores de sistemas y se ha comprobado que algunos
sistemas operativos están implementados como un conjunto de procesos o hilos.
PRINCIPIOS GENERALES DE LA CONCURRENCIA
En un sistema multiprogramado con un único procesador, los procesos se
intercalan en el tiempo aparentando una ejecución simultánea. Aunque no se
logra un procesamiento paralelo y produce una sobrecarga en los intercambios
de procesos, la ejecución intercalada produce beneficios en la eficiencia del
procesamiento y en la estructuración de los programas.
La intercalación y la superposición pueden contemplarse como ejemplos de
procesamiento concurrente en un sistema monoprocesador, los problemas son
consecuencia de la velocidad de ejecución de los procesos que no pueden
predecirse y depende de las actividades de otros procesos, de la forma en que
el sistema operativo trata las interrupciones surgen las siguientes dificultades:
Compartir recursos globales es riesgoso Para el sistema operativo es difícil
gestionar la asignación óptima de recursos. Las dificultades anteriores también
se presentan en los sistemas multiprocesador.
El hecho de compartir recursos ocasiona problemas, por esto es necesario
proteger a dichos recursos.
Los problemas de concurrencia se producen incluso cuando hay un único
procesado
LABORES DEL SISTEMA OPERATIVO
Elementos de gestión y diseño que surgen por causa de la concurrencia:
1) El sistema operativo debe seguir a los distintos procesos activos
2) El sistema operativo debe asignar y retirar los distintos recursos a cada
proceso activo, entre estos se incluyen:
_Tiempo de procesador
_Memoria
_Archivos
_Dispositivos de E/S
3) El sistema operativo debe proteger los datos y los recursos físicos de cada
proceso contra injerencias no intencionadas de otros procesos.
4) Los resultados de un proceso deben ser independientes de la velocidad a la
que se realiza la ejecución de otros procesos concurrentes.
Para abordar la independencia de la velocidad debemos ver las formas en las
que los procesos interactúan.
INTERACCIÓN ENTRE PROCESOS
Se puede clasificar los en que interactúan los procesos en función del nivel de
conocimiento que cada proceso tiene de la existencia de los demás. Existen tres
niveles de conocimiento:
1) Los procesos no tienen conocimiento de los demás: son procesos
independientes que no operan juntos. Ej: la multiprogramación de procesos
independientes. Aunque los procesos no trabajen juntos, el sistema operativo se
encarga de la “competencia” por los recursos.
2) Los procesos tienen un conocimiento indirecto de los otros: los procesos no
conocen a los otros por sus identificadores de proceso, pero muestran
cooperación el objeto común.
3) Los procesos tienen conocimiento directo de los otros: los procesos se
comunican por el identificador de proceso y pueden trabajar conjuntamente.
Competencia entre procesos por los recursos
Los procesos concurrentes entran en conflicto cuando compiten por el uso del
mismo recurso; dos o más procesos necesitan acceder a un recurso durante su
ejecución .Cada proceso debe dejar tal y como esté el estado del recurso que
utilice.
La ejecución de un proceso puede influir en el comportamiento de los procesos
que compiten. Por Ej. Si dos procesos desean acceder a un recurso, el sistema
operativo le asignará el recurso a uno y el otro tendrá que esperar.
Cuando hay procesos en competencia, se deben solucionar tres problemas de
control: la necesidad de exclusión mutua. Suponiendo que dos procesos quieren
acceder a un recurso no compartible. A estos recursos se les llama “recursos
críticos” y la parte del programa que los utiliza es la “sección crítica” del
programa. Es importante que sólo un programa pueda acceder a su sección
crítica en un momento dado.
Hacer que se cumpla la exclusión mutua provoca un interbloqueo.
Otro problema es la inanición si tres procesos necesitan acceder a un recurso,
P1 posee al recurso, luego lo abandona y le concede el acceso al siguiente
proceso P2, P1 solicita acceso de nuevo y el sistema operativo concede el
acceso a P1 YP2 alternativamente, se puede negar indefinidamente a P3 el
acceso al recurso.
El control de competencia involucra al sistema operativo, porque es el que
asigna los recursos.
Cooperación entre procesos por compartimiento Comprende los procesos que
interactúan con otros sin tener conocimiento explícito de ellos. Ej. : Varios
procesos pueden tener acceso a variables compartidas.
Los procesos deben cooperar para asegurar que los datos que se comparten se
gestionan correctamente. Los mecanismos de control deben garantizar la
integridad de los datos compartidos.
Cooperación entre procesos por comunicación Los distintos procesos participan
en una labor común que une a todos los procesos.
La comunicación sincroniza o coordina las distintas actividades, está formada
por mensajes de algún tipo. Las primitivas para enviar y recibir mensajes, vienen
dadas como parte del lenguaje de programación o por el núcleo del sistema
operativo
REQUISITOS PARA LA EXCLUSIÓN MUTUA
Sólo un proceso, de todos los que poseen secciones críticas por el mismo
recurso compartido, debe tener permiso para entrar en ella en un momento
dado. Un proceso que se interrumpe en una sección no crítica debe hacerlo sin
interferir con los otros procesos. Un proceso no debe poder solicitar acceso a
una sección crítica para después ser demorado indefinidamente, no puede
permitirse el interbloqueo o la inanición. Si ningún proceso está en su sección
crítica, cualquier proceso que solicite entrar en la suya debe poder hacerlo sin
demora. No se debe suponer sobre la velocidad relativa de los procesos o el
número de procesadores. Un proceso permanece en su sección crítica por un
tiempo finito. Una manera de satisfacer los requisitos de exclusión mutua es
dejar la responsabilidad a los procesos que deseen ejecutar concurrentemente.
Tanto si son programas del sistema como de aplicación, los procesos deben
coordinarse unos con otros para cumplir la exclusión mutua, sin ayuda del
lenguaje de programación o del sistema operativo. Estos métodos se conocen
como soluciones por software.
EXCLUSIÓN MUTUA: SOLUCIONES POR SOFTWARE
Pueden implementarse soluciones de software para los procesos concurrentes
que se ejecuten en máquinas monoprocesador o multiprocesador con memoria
principal compartida.
ALGORITMO DE DEKKER
La solución se desarrolla por etapas. Este método ilustra la mayoría de los
errores habituales que se producen en la construcción de programas
concurrentes.
Primer intento
Cualquier intento de exclusión mutua debe depender de algunos mecanismos
básicos de exclusión en el hardware. El más habitual es que sólo se puede
acceder a una posición de memoria en cada instante, teniendo en cuenta esto
se reserva una posición de memoria global llamada turno. Un proceso que
desea ejecutar su sección crítica primero evalúa el contenido de turno. Si el valor
de turno es igual al número del proceso, el proceso puede continuar con su
sección crítica. En otro caso el proceso debe esperar. El proceso en espera, lee
repetitivamente el valor de turno hasta que puede entrar en su sección crítica.
Este procedimiento se llama espera activa.
Después de que un proceso accede a su sección crítica y termina con ella, debe
actualizar el valor de turno para el otro proceso.
Segundo intento:
Cada proceso debe tener su propia llave de la sección crítica para que, si uno de
ellos falla, pueda seguir accediendo a su sección crítica; para esto se define un
vector booleano señal. Cada proceso puede evaluar el valor de señal del otro,
pero no modificarlo. Cuando un proceso desea entrar en su sección crítica,
comprueba la variable señal del otro hasta que tiene el valor falso (indica que el
otro proceso no está en su sección crítica). Asigna a su propia señal el valor
cierto y entra en su sección crítica. Cuando deja su sección crítica asigna falso a
su señal.
Si uno de los procesos falla fuera de la sección crítica, incluso el código para dar
valor a las variables señal, el otro proceso no se queda bloqueado. El otro
proceso puede entrar en su sección crítica tantas veces como quiera, porque la
variable señal del otro proceso está siempre en falso. Pero si un proceso falla en
su sección crítica o después de haber asignado cierto a su señal, el otro proceso
estará bloqueado permanentemente.
Tercer intento
El segundo intento falla porque un proceso puede cambiar su estado después de
que el otro proceso lo ha comprobado pero antes de que pueda entrar en su
sección crítica.
Si un proceso falla dentro de su sección crítica, incluso el código que da valor a
la variable señal que controla el acceso a la sección crítica, el otro proceso se
bloquea y si un proceso falla fuera de su sección crítica, el otro proceso no se
bloquea.
Si ambos procesos ponen sus variables señal a cierto antes de que ambos
hayan ejecutado una sentencia, cada uno pensará que el otro ha entrado en su
sección crítica, generando así un interbloqueo.
Cuarto intento
En el tercer intento, un proceso fijaba su estado sin conocer el estado del otro.
Se puede arreglar esto haciendo que los procesos activen su señal para indicar
que desean entrar en la sección crítica pero deben estar listos para desactivar la
variable señal y ceder la preferencia al otro proceso.
Existe una situación llamada bloqueo vital, esto no es un interbloqueo, porque
cualquier cambio en la velocidad relativa de los procesos rompería este ciclo y
permitiría a uno entrar en la sección crítica. Recordando que el interbloqueo se
produce cuando un conjunto de procesos desean entrar en sus secciones
críticas, pero ninguno lo consigue. Con el bloqueo vital hay posibles secuencias
de ejecución con éxito.
Una solución correcta
Hay que observar el estado de ambos procesos, que está dado por la variable
señal, pero es necesario imponer orden en la actividad de los procesos para
evitar el problema de “cortesía mutua”. La variable turno del primer intento puede
usarse en esta labor, indicando que proceso tiene prioridad para exigir la entrada
a su sección crítica.
ALGORITMO DE PETERSON
El algoritmo de Deker resuelve el problema de la exclusión mutua pero mediante
un programa complejo, difícil de seguir y cuya corrección es difícil de demostrar.
Peterson ha desarrollado una solución simple y elegante. Como antes, la
variable global señal indica la posición de cada proceso con respecto a la
exclusión mutua y la variable global turno resuelve los conflictos de
simultaneidad.
Considérese el proceso P0. Una vez que ha puesto señal[0] a cierto, P1 no
puede entrar en su sección crítica. Si P1 esta aun en su sección crítica,
entonces señal[1] = cierto y P0 está bloqueado en su bucle while. Esto significa
que señal[1] es cierto y turno = 1. P0 puede entrar en su sección crítica cuando
señal[1] se ponga a falso o cuando turno se ponga a 0. Considérense ahora los
siguientes casos exhaustivos:
P1 no está interesado en entrar en su sección crítica. Este caso es imposible
porque implica que señal[1] = falso. P1 está esperando entrar en su sección
crítica. Este caso es también imposible porque si turno = 1, P1 podría entrar en
su sección crítica. P1 entra en su sección crítica varias veces y monopoliza el
acceso a ella. Esto no puede pasar porque P1 está obligado a dar a P0 una
oportunidad poniendo turno a 0 antes de cada intento de entrar en su sección
crítica. Así pues, se tiene una solución posible al problema de la exclusión mutua
para dos procesos. Es más, el algoritmo de Peterson se puede generalizar
fácilmente al caso de n procesos.
Disciplina de cola
La disciplina de cola mas simple es la de primero en llegar/ primero en salir, pero
ésta puede no ser suficiente si algunos mensajes son mas urgentes que otros.
Una alternativa es permitir la especificación de prioridades de los mensajes, en
función del tipo de mensaje o por designación del emisor. Otra alternativa es
permitir al receptor examinar la cola de mensajes y seleccionar el mensaje a
recibir a continuación.
Exclusión mutua
Supóngase que se usan primitivas receive bloqueantes y send no bloqueantes.
Un conjunto de procesos concurrentes comparten un buzón, exmut, que puede
ser usado por todos los procesos para enviar y recibir. El buzón contiene
inicialmente un único mensaje, de contenido nulo. Un proceso que desea entrar
en su sección crítica intenta primero recibir el mensaje. Si el buzón está vacío, el
proceso se bloquea. Una vez que un proceso ha conseguido el mensaje, ejecuta
su sección crítica y, después, devuelve el mensaje al buzón. De este modo, el
mensaje funciona como testigo que se pasa de un proceso a otro.
Esta técnica supone que si hay más de un proceso ejecutando la acción receive
concurrentemente, entonces:
Si hay un mensaje, se entrega sólo a uno de los procesos y los otros se
bloquean. Si el buzón está vacío, todos los procesos se bloquean; cuando haya
un mensaje disponible, sólo se activará y tomará el mensaje uno de los procesos
bloqueados.
EXCLUSIÓN MUTUA: SOLUCIONES POR HARDWARE
INHABILITACIÓN DE INTERRUPCIONES
En una máquina monoprocesador, la ejecución de procesos concurrentes no
puede superponerse; los procesos solo pueden intercalarse. Es más, un proceso
continuará ejecutándose hasta que solicite un servicio el sistema operativo o
hasta que sea interrumpido. Por lo tanto, para garantizar la exclusión mutua, es
suficiente con impedir que un proceso sea interrumpido. Esta capacidad puede
ofrecerse en forma de primitivas definidas por el núcleo del sistema para habilitar
o inhabilitar las interrupciones. Un proceso puede hacer cumplir la exclusión
mutua del siguiente modo:
While (cierto)
{
/*inhabilitar interrupciones */;
/* sección critica */;
/* habilitar interrupciones */;
/* resto */;
}
Puesto que la sección crítica no puede ser interrumpida, la exclusión mutua está
garantizada. Sin embargo, el precio de esta solución es alto. La eficiencia de la
ejecución puede verse notablemente degradada debido a que se limita la
capacidad del procesador para intercalar programas. Un segundo problema es
que está técnica no funciona en arquitecturas de multiprocesador. Cuando el
sistema tenga más de un procesador, es posible (y habitual) que haya más de
un proceso ejecutándose al mismo tiempo. En este caso, inhabilitar las
interrupciones no garantiza la exclusión mutua.
INSTRUCCIONES ESPECIALES DE MAQUINA
En configuraciones multiprocesador, varios procesadores comparten el acceso a
una memoria principal común. En este caso, no hay relación maestro/esclavo,
sino que los procesadores funcionan independientemente en una relación de
igualdad. No hay un mecanismo de interrupciones entre los procesadores en el
que se pueda basar la exclusión mutua.
A nivel de hardware, como se ha mencionado, los accesos a posiciones de
memoria excluyen cualquier otro acceso a la misma posición. Con esta base, los
diseñadores han propuesto varias instrucciones de máquina que realizan dos
acciones atómicamente, tales cono leer y escribir o leer y examinar, sobre una
misma posición de memoria en un único ciclo de lectura de instrucción.
Puesto que estas acciones se realizan en un único ciclo de instrucción, no están
sujetas a injerencias por parte de otras instrucciones.
-La instrucción COMPARAR Y FIJAR (TS, Test and Set)puede definirse de la
siguiente forma:
booleano TS(int i)
{
if (I==0)
{
I=1;
return cierto;
}
else
{
return falso;
}
}
La instrucción examina el valor de su argumento i. Si el valor es 0 , lo cambia por
1 y devuelve cierto. En otro caso, el valor no se modifica y se devuelve falso. La
función Comparar y Fijar se ejecuta atómicamente en su totalidad, es decir, no
esta sujeta a interrupciones.
La instrucción INTERCAMBIAR se puede definir como sigue:
void intercambiar (int registro, int memoria)
{
int temp;
temp = memoria;
memoria = registro;
registro = temp;
}
Esta instrucción intercambia el contenido de un registro con el de una posición
de memoria. Durante la ejecución de la instrucción, se bloquea el acceso a la
posición de memoria de cualquier otra instrucción que haga referencia a la
misma posición.
Propiedades de las soluciones con instrucciones de maquina
El uso de instrucciones especiales de la maquina para hacer cumplir la exclusión
mutua tiene varias ventajas:
Es aplicable a cualquier número de procesos en sistemas con memoria
compartida, tanto de monoprocesador como de multiprocesador. Es simple y
fácil de verificar. Puede usarse para disponer de varias secciones críticas; cada
sección crítica puede definirse con su propia variable. Algunas desventajas
importantes son las siguientes:
SE EMPLEA ESPERA ACTIVA. Así pues, mientras un proceso está esperando
para acceder a la sección crítica, continúa consumiendo tiempo del procesador.
PUEDE PRODUCIRSE INANICIÓN. Cuando un proceso abandona la sección
crítica y hay más de un proceso esperando, la selección es arbitraria. Así pues
se podría denegar el acceso a algún proceso indefinidamente. PUEDE
PRODUCIRSE INTERBLOQUEO. Supóngase la siguiente escena en un sistema
monoprocesador. El proceso “P1″ ejecuta una instrucción especial (sea TS o
Intercambiar) y entra su sección crítica. Se interrumpe a “P1″ para dar el
procesador a “P2″, que tiene mayor prioridad. Si “P2″ intenta ahora usar el
mismo recurso que “P1″, se le negará el acceso por el mecanismo de exclusión
mutua. De este modo, “P2″ entrará en un bucle de espera activa. Sin embargo,
“P1″ nunca será expedido porque su prioridad es menor que la del proceso listo
“p2″.
SEMÁFOROS
Para solucionar problemas de procesos concurentes, se diseño un S.O. como un
conjunto de procesos secuenciales, eficiente y fiables para dar soporte a la
cooperación. Los procesos de usuario podrían utilizar estos mecanismos si el
procesador y el S.O. los hacían disponible.
El principio fundamental es el siguiente, 20+ procesos pueden cooperar por
medio de simples señales, de manera que se pueda obligar a un proceso a
detener en una posición determinada hasta que reciba una señal específica.
Para la señalización se usan variables especiales llamadas semáforos “S”, los
procesos ejecutan las primitivas wait(s) si la señal aun no se transmitió, el
proceso se suspende hasta que tiene lugar la transmisión.
A los semáforos se los contemplan como variables que tienen un N° entero
sobre el que se definen las siguientes operaciones:
un semáforo puede iniciarse con un valor negativo la operación wait disminuye el
valor del semáforo. Si el valor no es positivo el proceso que ejecuta wait se
bloquea. las operaciones signal incrementa el N° del semáforo. Si el valor es
positivo se desbloquea el proceso bloqueado por una operación wait. No hay
forma de examinar o manipular los semáforos aparte de estas tres operaciones.
Las primitivas wait y signal se suponen atómicas, es decir no pueden ser
interrumpidas y cada rutina puede considerarse como un peso indivisible.
Un semáforo solo puede tomar los valores 0 y 1. Son más sencillos de implantar
y pueden demostrarse que tienen la misma potencia de expresión que los
semáforos generales.
En ambos semáforos se emplean una cola para mantener los procesos en
espera, la cuestión reside en el orden en que se retiran los procesos de la cola.
La política utilizada el la de FIFO; el proceso que estuvo bloqueado durante mas
tiempo se libera de la cola, se denomina semáforo robusto (incluye esta
estrategia). Un semáforo débil no especifica el orden en que se retiran los
procesos de la cola.
Los semáforos robustos garantizan la inexistencia de inanición en el algoritmo
de exclusión mutua, pero no así en los semáforos débiles, se supone que los
semáforos son siempre robustos ya que son los más adecuados y porque son
los tipos de semáforos que más incluyen los S.O.
Implementación de los semáforos. Como se menciono anteriormente es
impredecible que las operaciones wait y signal sean implementadas como
primitivas atómicas.
La esencia del problema del productor/consumidor, es la exclusion mutua: solo 1
proceso puede manipular un semáforo a la vez, en una operación wait o signal.
Se pueden utilizar cualquier esquema de software con los algoritmos de Dekker
o Peterson los que suponen una sobrecarga de procesos sustancial. Otra
alternativa es usar uno de los esquemas de soporte del hardware p/la exclusion
mutua..
En sistemas monoprocesador procesador, se pueden inhibir las interrupciones
durante una operación wait o signal.
MONITORES
Los monitores son estructuras de un lenguaje de programación que ofrecen una
funcionalidad equivalente a las de los semáforos pero son más fáciles de
controlar. El concepto de monitor fue definido por primera vez en [HOAR 74] . La
estructura de monitor se ha implementado en varios lenguajes de programación
como: Pascal concurrente, Modulo-2, Java, etc.
En concreto, para una lista enlazada se puede necesitar un cierre que bloquee
todas las listas enlazadas o bien un cierre por cada elemento de una lista.
Monitores con Señales: ( definición de Hoare )
Un monitor es un modulo de software que consta de uno o más procedimientos,
una secuencia de inicio y uno datos locales. Sus características son las
siguientes:
Solo los procedimientos del monitor acceden a variables de datos locales. Un
proceso entra en el monitor invocando a uno de sus procedimientos. En el
monitor solo un proceso puede ser ejecutado en un momento dado; cualquier
otro proceso quedara suspendido esperando la disponibilidad del monitor. Al ser
un proceso por vez, el monitor puede ofrecer un servicio de exclusión mutua
fácilmente. Así una estructura de datos puede protegerse situándola dentro de
un monitor.
Los monitores deben ofrecer herramientas de sincronización. Por ejemplo: si un
proceso llama a un monitor y una vez dentro de él el proceso queda suspendido
esperando alguna condición, hará falta un servicio que libere al monitor y lo deje
disponible para el siguiente proceso. Mas tarde cuando la condición se cumpla el
proceso suspendido podrá regresar al monitor y ejecutarse desde el momento
de la suspensión.
El monitor proporciona variables de condición que son accesibles solo desde
dentro del monitor.
Hay dos funciones para operar variables de condición:
cwait ©: suspende la ejecución del proceso que llama bajo la condición “c”. El
monitor está ahora disponible para otro proceso. csignal ©: retorna la ejecución
de un proceso suspendido después de un cwait, bajo la misma condición. Si hay
varios procesos elige uno de ellos. Si un proceso de monitor ejecuta un csignal y
no hay tareas esperando entonces el csignal de pierde.
Aunque un proceso puede entrar al monitor llamando a cualquiera de sus
procedimientos, se puede decir que el monitor tiene un solo punto de acceso,
custodiado para que solo un proceso este en el monitor en un instante dado. Si
existen otros procesos tratando de entrar al monitor, estos se colocan en una
cola de procesos suspendidos esperando la disponibilidad del monitor.
Un proceso dentro de un monitor puede suspenderse a sí mismo,
temporalmente, bajo la condición X ejecutando cwait(x), entonces se coloca en
una cola de procesos que esperan que cambie la condición X entonces ejecuta
un csignal(x) que avisa a la cola de condición correspondiente de que la
condición a cambiado.
En el código se puede apreciar la solución al problema de productor /
consumidor usando monitores:
El modulo monitor, buffers_acotado, controla el buffer para almacenar y retirar
caracteres. El monitor incluye dos variables de condición:
No-lleno es verdadero su hay lugar para agregar al menos un carácter.
No-vació es verdadero si hay al menos un carácter en el buffer.
Un productor solo puede agregar caracteres al buffer mediante el procedimiento
añadir del monitor; el productor no tiene acceso directo al buffer. El
procedimiento comprueba si hay espacio en el buffer, mediante la condición nolleno, si no lo hay el proceso queda suspendido y cualquier otro proceso
(consumidor o productor) puede entrar al monitor. Luego, cuando el buffer ya no
esta lleno, el proceso se retira de la cola y es reactivado. Luego de añadir un
carácter el proceso activa la condición no-vació.
La estructura misma del monitor garantiza la exclusión mutua (solo un proceso
por vez puede acceder al buffer). Sin embargo, el programador debe situar
correctamente las primitivas cwait( ) y csignal( ) en el monitor para evitar que los
procesos depositen elementos en un buffer lleno o los extraigan de uno vació.
Un proceso sale del monitor inmediatamente después de ejecutar csignal( ).
Si csignal( ) se ejecuta antes del final entonces ese proceso libera el monitor y
esta colocado en una lista de procesos suspendidos. Un nuevo proceso puede
entrar el monitor.
Si no hay procesos esperando en la condición X, la ejecución de csignal (x) no
tiene efecto.
Es posible cometer errores en la sincronización de los monitores, por ejemplo, si
se omite cualquiera de las funciones csignal() en el monitor buffer _ acotado los
procesos que entran en la cola de condición permanecen colgados
permanentemente. Sin embargo la ventaja de los monitores es que todas las
funciones de sincronización están incluidas dentro del monitor, lo que permite
una fácil detección y corrección de fallas de sincronización.
Monitores con Notificación y Difusión (definición de Lampson y Redell)
Son varios los inconvenientes que presenta la solución de Hoare:
-Si el proceso que ejecuta el csignal( ) no ha terminado en el monitor, se
necesitaran dos cambios de procesos adicionales: uno para suspender el
proceso y otro para reanudarlo.
-La planificación de procesos asociados con las señales debe ser muy fiable. Si
un proceso ejecuta un csignal ( ), el proceso de la cola de condición
correspondiente debe activarse de inmediato, antes de que ingrese otro proceso
del exterior o cambie la condición bajo la que se activó el proceso. Otro caso
seria que un proceso productor escribe un carácter en el buffer y falla antes de
dar la señal, entonces la cola de condición no-vacía se colgaría para siempre.
Lampson y Redell desarrollaron una definición de monitores para el lenguaje
MESA [Lamp 80]. La estructura de mesa reemplaza la primitiva csignal( ) por
cnotify( ). Cuando un proceso ejecuta cnotify(x) envía una notificación a la cola
de condición X, lo cual no significa que el proceso que esta ocupando el monitor
vaya a detenerse, simplemente el cnotify(x) avisa al proceso de la cola de
condición correspondiente de que será reanudado en un futuro cercano. Puesto
que esta no garantiza que un proceso exterior entre al monitor, el proceso debe
comprobar la condición nuevamente.
En el código, la sentencia IF se reemplaza por un bucle While, lo cual genera
una evaluación extra de la variable, pero sin embargo no hay cambios de
procesos extra.
Una modificación útil seria asociar un temporizador de guardia a cnotify( ) que
permitiría que un proceso que ha esperado durante el intervalo máximo sea
situado en estado de listo, independientemente de sí se ha notificado la
condición.
Con la norma de notificar a los procesos en lugar de reactivarlos, es posible
añadir una primitiva de difusión cbroadcast. La difusión provoca que todos los
procesos que están esperando por una condición se coloquen en el estado de
listo. Esto es útil cuando un proceso no sabe cuantos procesos deben
reactivarse.
El método Lampson/Redell es menos propenso a errores debido a que cada
procedimiento comprueba la condición luego de ser despertado, por medio de la
instrucción while, un proceso puede realizar una señal o una difusión
incorrectamente sin provocar un error en el programa que la recibe.
Además este modelo presta un método mas modular de construcción de
programas.
Hay dos niveles de condición que deben satisfacerse para los procesos
secuenciales cooperantes.
Estructura de datos consistentes: significa que el monitor hace cumplir la
exclusión mutua y concluye la operación de entrada o salida antes de permitir
cualquier otra operación sobre el buffer. La misma condición del nivel 1 y,
además disponer de suficiente memoria para que este proceso pueda completar
su solicitud de asignación. PASO DE MENSAJES
Son 2 los requisitos básicos que deben satisfacerse cuando los procesos
interactúan entre si.
Ellos son:
La sincronización La comunicación Los procesos tienen que sincronizarse para
cumplir la exclusión mutua, los procesos cooperantes pueden necesitar
intercambiar información.
El paso de mensajes es un método que permite que se realice ambas funciones.
Este método tiene la ventaja de que es de fácil implementación en sistemas
distribuidos y también es sistemas de multiprocesador y monoprocesador de
memoria compartida.
La funcionalidad real del paso de mensajes, generalmente, se da por medio de
un par de primitivas:
send(destino, mensaje)
receive(origen, mensaje)
Este es el conjunto mínimo de operaciones necesarias para que los procesos
puedan dedicarse al paso de mensajes.
SINCRONIZACION
La comunicación de un mensaje entre 2 procesos implica cierto nivel de
sincronización entre ambos. El receptor no puede recibir un mensaje hasta que
sea enviado por otro proceso. Además hace falta especificar que le sucede a un
proceso después de ejecutar una primitiva SEND o RECEIVE.
Considérese en primer lugar la primitiva send. Cuando se ejecuta una primitiva
send en un proceso, hay 2 posibilidades: o bien el proceso emisor se bloquea
hasta que recibe el mensaje o no se bloquea. Igualmente cuando un proceso
ejecuta una primitiva RECEIVE, existen 2 opciones:
1) Si previamente se ha enviado algún mensaje, este es recibido y continua la
ejecución.
2) Si no hay ningún mensaje esperando entonces:
a) el proceso se bloquea hasta que llega un mensaje o,
b) el proceso continúa ejecutando, abandonando el intento de recepción.
El emisor y el receptor pueden ser bloqueantes o no bloqueantes.
Existen 3 tipos de combinaciones pero un sistema solo implementa uno o dos.
I) Envío bloqueante, recepción bloqueante: tanto el emisor como el receptor se
bloquean hasta que llega el mensaje; esta técnica se conoce como rendezvous.
II) Envío no bloqueante, recepción bloqueante: aunque el emisor puede
continuar, el receptor se bloquea hasta que llega el mensaje solicitado. Es la
combinación más útil.
III) Envío no bloqueante, recepción no bloqueante: nadie debe esperar.
El send no bloqueante es la forma más natural para muchas tareas de
programación concurrente. Un posible riesgo del send no bloquente es que por
error puede llevar a una situación en la que el proceso genere mensajes
repetidamente.
Para el receive, la versión bloqueante es la mas natural para muchas tareas de
programación concurrente. En general, un proceso que solicita un mensaje
necesitara la información esperada antes de continuar.
DIRECCIONAMIENTO
Es necesario disponer de alguna forma de especificar en la primitiva send que
proceso va a recibir el mensaje. La mayoría de las implementaciones permiten a
los procesos receptores indicar el origen del mensaje que se va a recibir.
Los distintos esquemas para hacer referencia a los procesos en las primitivas
send y receive se encuadran dentro de 2 categorías:
1) Direccionamiento directo: la primitiva send incluye una identificación
específica del proceso de destino.
La primitiva receive se puede gestionar de 2 formas:
Una posibilidad requiere que el proceso designe explícitamente un proceso
emisor. El proceso debe conocer de antemano de que proceso espera un
mensaje. En otros casos es imposible especificar el proceso de origen por
anticipado. 2) Direccionamiento indirecto: los mensajes no se envían
directamente del emisor al receptor, sino a una estructura de datos compartidos
formada por colas, que pueden guardar los mensajes temporalmente, que se
denominan BUZONES (mailboxes). Para que 2 procesos se comuniquen, uno
envía mensajes al buzón apropiado y el otro los retira. Una ventaja de este tipo
de direccionamiento es que se desacopla a emisor y receptor, asegurando
mayor flexibilidad en el uso de mensajes.
Relación entre emisores y receptores
UNO A UNO: permite que se establezca un enlace privado entre 2 procesos.
Aísla su interacción de injerencias erróneas de otros procesos. MUCHOS A
UNO: resulta útil para interacciones cliente-servidor. En este caso el buzón se
llama puerto. UNO A MUCHOS: permite un emisor y varios receptores. La
asociación de procesos a buzones puede ser ESTATICA o DINAMICA. Los
puertos suelen estar asociados estáticamente con algún proceso en particular.
El puerto se crea y se asigna al proceso permanentemente. Una relación de
UNO A UNO se define de forma estática y permanentemente. Cuando hay
varios emisores, la asociación a un BUZON puede realizarse dinámicamente. Se
pueden utilizar primitivas como CONECTAR o DESCONECTAR.
Propiedad del buzón. en el caso de 1 puerto, normalmente pertenece y se crea
por el RECPTOR. Entonces cuando se destruye el proceso, también se destruye
el puerto.
Para los buzones en general el S.O. ofrece un servicio de creación de buzones.
Son considerados como propiedad del proceso creador en cuyo caso se
destruyen junto con el proceso, o como propiedad del S.O., en este caso se
necesita una orden explicita para destruir el buzón.
FORMATO DE MENSAJES
Para algunos S.O. los diseñadores han elegido mensajes cortos y tamaños fijos
para minimizar procesamiento y coste de almacenamiento. Si se van a pasar
una gran cantidad de datos, estos pueden ponerse en un archivo y el mensaje
simplemente hará referencia a este archivo. Una solución más flexible es utilizar
mensajes de longitud variable.
DISCIPLINA DE COLA
La disciplina de cola más simple es FIFO, pero esta puede no ser suficiente para
mensajes más urgentes que otros. Una opción es habilitar la especificación de
prioridades de los mensajes, en función del tipo de mensajes o por designación
del emisor. Otra es permitir al receptor examinar la cola de mensajes y
seleccionar el mensaje a recibir a continuación.
EXCLUSION MUTUA
Con el siguiente algoritmo de muestra una forma de usar el PASO DE
MENSAJES para cumplir la exclusión mutua.
Se usan RECEIVE bloqueantes y SEND no bloqueantes. Unos procesos
concurrentes comparte un BUZON, EXMUT, que puede ser usado por todos los
procesos. EXMUT (buzón) tiene inicialmente un único mensaje nulo. Un proceso
que requiere entrar en su sección crítica intenta:
1) recibir el mensaje. Si el EXMUT(buzón) esta vacío, se bloquea el proceso.
2) Una vez que consiguió el mensaje, ejecuta su sección crítica y devuelve el
mensaje al buzón.
El mensaje funciona como un testigo(TOKEN) que se pasa de proceso a otro.
Esta técnica supone que si hay más de un proceso ejecutando la acción
RECEIVE concurrentemente, entonces:
Si hay un mensaje, se entrega solo a uno de los procesos y los demás se
bloquean. Si el buzón esta vacío, todos se bloquean cuando hay un mensaje,
solo se activara y tomara el mensaje uno de los procesos bloqueados.
PROBLEMA DE LOS LECTORES/ESCRITORES
Descripción del problema:
Existe un área de datos compartida entre una serie de procesos, algunos sólo
leen los datos (lectores) y otros sólo escriben datos (escritores). El problema es
satisfacer las siguientes condiciones:
1. Cualquier número de lectores puede leer el archivo simultáneamente.
2. En el archivo sólo puede escribir un escritor en cada instante.
3. Si un escritor está accediendo al archivo, ningún lector puede leerlo.
El problema general de exclusión mutua, consiste en permitir a cualquiera de los
procesos (lectores o escritores) leer o escribir en el área de datos. Esto hace
necesario declarar cualquier acceso como una sección crítica donde los
procesos tendrían que acceder uno a uno produciéndose intolerables retrasos,
además se debe impedir que los escritores interfieran unos con otros y también
que se realicen consultas mientras se llevan a cabo modificaciones
Aplicar la solución general al problema de los lectores/escritores sería
inaceptablemente lenta. En este caso más restrictivo es posible crear soluciones
más eficientes.
A continuación se examinan dos soluciones al problema:
PRIORIDAD A LOS LECTORES Es una solución que utiliza semáforos para
respetar la exclusión mutua. Se permite el acceso a varios lectores, pero
mientras que un escritor está accediendo a los datos compartidos, no se permite
acceder a ningún escritor o lector.
El primer lector que intenta acceder debe esperar en el semáforo, Cuando haya
al menos un lector, los lectores siguientes no necesitan esperar para entrar, se
les da prioridad. El problema es que un escritor estará esperando mientras que
haya al menos un lector leyendo, que luego podría dar paso a otro lector, en
este caso el lector estará sujeto a inanición.
Se utiliza una variable global contlect para mantener el número de lectores y el
semáforo x para que la actualización de contlect sea consistente. El semáforo
esem controla el acceso al recurso compartido.
/* program lectores_escntores*/
int contlect;
semáforo x = 1, esem=1;
void lector()
{
while (cierto)
{
wait(x);
contlect++;
If (contlect==1)
wait(esem);
signal(x);
LEER_UNIDAD();
wait(x);
contlect—;
If (contlect==0)
signal(esem);
signal(x);
}
}
void escritor()
{
while (cierto)
{
wait(esem);
ESCRIBIR_UNIDAD();
signal(esem);
}
}
vold main() {
contlect = 0;
parbegln(tector, escritor);
}
Una solución al problema de los lectores/escritores por medio de semáforos; los
lectores tienen prioridad.
2. PRIORIDAD A LOS ESCRITORES
Esta solución garantiza que no se permitirá acceder a los datos a ningún nuevo
lector una vez que, al menos, un escritor haya declarado su deseo de escribir.
Se utilizan los mismos semáforos que en la solución anterior y se añaden otros
más:
• Un semáforo Isem que inhibe todas las lecturas cuando al menos un escritor
desea acceder
• Una variable contesc que controla la activación de Isem
• Un semáforo y que controla la actualización de contesc
• Un semáforo y que controla la actualización de contesc
• Un semáforo z donde se encolan los lectores cuando ya hay uno en lsem
/* program lectores_escritores */
Int contlec, contesc;
semáforo x=1, y =1, z=1, esem=1, lsem=1;
void lector()
{
while (cierto)
{
wait(z);
wait(lsem);
wait(x);
contlect++;
if (contlect = = 1)
{
wait(esem);
}
signal(x);
signal(lsem);
signal(z);
LEER_UNIDAD();
wait(x);
contlect—;
if (contlect == 0)
signal(esem);
signal(x);
}
}
void escritor()
{
while (cierto)
{
wait(y);
contesc++;
if (contesc = = 1)
wait(lsem) ;
signal(y);
wait(esem);
ESCRIBIR_UNIDAD();
signal(esem);
wait(y);
contesc—;
If (contesc== 0)
signal(lsem);
signal(y);
}
}
void mailn()
{
contlect = contesc = 0;
parbegin (lector, escritor);
}
2.13 Principios del Interbloqueo
2.14 Acciones Realizar en Interbloqueo prevención, detección, predicción y
evitar
CONDICIONES PARA PRODUCIR INTERBLOQUEO
En la política del sistema operativo, deben darse tres condiciones para que
pueda producirse un interbloqueo:
1- Condición de exclusión mutua: Cada recurso esta asignado a un único
proceso o esta disponible.
2- Condición de posesión y espera: Los procesos que tienen, en un momento
dado, recursos asignados con anterioridad, pueden solicitar nuevos recursos.
3- Condición de no apropiación: Los recursos otorgados con anterioridad no
pueden ser forzados a dejar un proceso. El proceso que los posee debe
liberarlos en forma explicita.
En la mayoría de los casos, estas condiciones son bastantes necesarias. La
exclusión mutua hace falta para asegurar la consistencia de resultados y la
integridad de la base de datos. De forma similar, la apropiación no se puede
aplicar arbitrariamente y, cuando se encuentran involucrados recursos de datos,
debe estar acompañada de un mecanismo de recuperación y reanulación, que
devuelva un proceso y sus recursos a un estado previo adecuado, desde el que
el proceso puede finalmente repetir sus acciones.
Puede no existir interbloqueo con solo estas tres condiciones. Para que se
produzca interbloqueo, se necesita una cuarta condición:
4- Condición de espera circular (o circulo vicioso de espera): Debe existir una
cadena circular de dos o mas procesos, cada uno de los cuales espera un
recurso poseído por el siguiente miembro de la cadena.
Las tres primeras condiciones son necesarias, pero no suficientes, para que
exista interbloqueo. La cuarta condición es, en realidad, una consecuencia
potencial de las tres primeras. Es decir, dado que se producen las tres primeras
condiciones, puede ocurrir una secuencia de eventos que desemboque en un
circulo vicioso de espera irresoluble. El circulo de espera de la condición 4 es
irresoluble porque se mantienen las tres primeras condiciones. Las cuatro
condiciones en conjunto constituyen una condición necesaria y suficiente para el
interbloqueo.
PREVENCIÓN DEL INTERBLOQUEO
La estrategia básica de la prevención del interbloqueo consiste, a grandes
rasgos, en diseñar su sistema de manera que esté excluida, a priori, la
posibilidad de interbloqueo.
Los métodos para prevenir el interbloqueo son de dos tipos:
- Los métodos indirectos que consisten en impedir la aparición de alguna de las
tres condiciones necesarias para que se de el interbloqeo.
- Los métodos directos que consisten en evitar la aparición del circulo vicioso de
espera.
PREDICCIÓN DEL INTERBLOQUEO
Una forma de resolver el problema del interbloqueo, que se diferencia sutilmente
de la prevención, es la predicción del interbloqueo. En la prevención de
interbloqueo, se obligaba a las solicitudes de recursos a impedir que sucediera ,
por lo menos, alguna de las cuatro condiciones de interbloqueo. Esto se hace
indirectamente, impidiendo la aparición de una de las tres condiciones
necesarias (exclusión mutua, retención y espera, no apropiación) o
directamente, impidiendo la aparición de un circulo viciosos de espera. Se llega
así a un uso ineficiente de los recursos y una ejecución ineficiente de los
procesos. Con predicción del interbloqueo, por otro lado, se pueden alcanzar las
tres condiciones necesarias, pero se realizan elecciones acertadas para
asegurar que nunca se llega al punto de interbloqueo. La predicción, por lo tanto,
permite más concurrencia que la prevención. Con predicción del interbloqueo, se
decide dinámicamente si la petición actual de asignación de un recurso podría,
de concederse, llevar potencialmente a un interbloqueo. La predicción del
interbloqueo necesita, por lo tanto, conocer las peticiones futuras de recursos.
Enfoques para la predicción del interbloqueo: - - No iniciar un proceso si sus
demandas pueden llevar a interbloqueo. - - No conceder una solicitud de
incrementar los recursos de un proceso si esta asignación puede llevar a
interbloqueo.
- DETECCIÓN DEL INTERBLOQUEO
- Las estrategias de prevención de interbloqueo son muy conservadoras;
resuelven el problema limitando el acceso a recursos e imponiendo restricciones
sobre los procesos. En cambio, las estrategias de detección de interbloqueo, no
limitan el acceso a recursos ni restringen las acciones del proceso. Con la
detección del interbloqueo, se concederán los recursos que los procesos
necesiten siempre que sea posible. Periódicamente, el S. O. ejecuta un
algoritmo que permite detectar la condición de circulo vicioso de espera. - La
detección del interbloqueo es el proceso de determinar si realmente existe un
interbloqueo e identificar los procesos y recursos implicados en él. Una
posibilidad detectar un interbloqueo es monitorear cada cierto tiempo el estado
de los recursos. Cada vez que se solicita o se devuelve un recurso, se actualiza
el estado de los recursos y se hace una verificación para observar si existe algún
ciclo. - Este método está basado en suponer que un interbloqueo no se presente
y que los recursos del sistema que han sido asignados, se liberarán en el
momento que otro proceso lo requiera.
- Algoritmo de detección del interbloqueo - Una comprobación para interbloqueo
puede hacerse con igual o menor frecuencia que cada solicitud de recursos,
dependiendo de que tan probable es que ocurra un interbloqueo. Comprobar
cada solicitud de recursos tiene dos ventajas: Conduce a la detección temprana
y el algoritmo es simple, de manera relativa porque se basa en cambios
crecientes al estado del sistema. Además, las comprobaciones frecuentes
consumen un tiempo considerable de procesador. - Los algoritmos de detección
de bloqueos implican cierta sobrecarga en tiempo de ejecución: - surge el
siguiente interrogante:
- ¿ compensa la sobrecarga implicita en los algoritmos de detección de
bloqueos, el ahorro potencial de localizarlos y romperlos ?. - - El empleo de
algoritmos de detección de interbloqueo implica cierto gasto extra durante la
ejecución. Así pues, se presenta de nuevo la cuestión de costeabilidad, tan
habitual en los sistemas operativos. Los algoritmos de detección de interbloqueo
determinan por lo general si existe una espera circular - RECUPERACIÓN DE
INTERBLOQUEO - - Cuando se ha detectado que existe un interbloqueo,
podemos actuar de varias formas. Una posibilidad es informar al operador que
ha ocurrido un interbloqueo y dejar que el operador se ocupe de él
manualmente. La otra posibilidad es dejar que el sistema se recupere
automáticamente del interbloqueo. Dentro de esta recuperación automática
tenemos dos opciones para romper el interbloqueo: Una consiste en abortar uno
o más procesos hasta romper la espera circular, y la segunda es apropiar
algunos recursos de uno o más de los procesos bloqueados. - La recuperación
después de un interbloqueo se complica porque puede no estar claro que el
sistema se haya bloqueado. Las mayorías de los Sistemas Operativos no tienen
los medios suficientes para suspender un proceso, eliminarlo del sistema y
reanudarlo más tarde. - Actualmente, la recuperación se suele realizar
eliminando un proceso y quitándole sus recursos. El proceso eliminado se
pierde, pero gracias a esto ahora es posible terminar. Algunas veces es
necesario, eliminar varios procesos hasta que se hayan liberado los recursos
necesarios para que terminen los procesos restantes. - Los procesos pueden
eliminarse de acuerdo con algún orden de prioridad, aunque es posible que no
existan prioridades entre los procesos bloqueados, de modo que el operador
necesita tomar una decisión arbitraria para decidir que procesos se eliminarán.
- Recuperación Manual - Está forma de recuperación consiste en avisarle al
administrador o al operador del sistema que se ha presentado un interbloqueo, y
será el administrador el que solucione dicho problema de la manera más
conveniente posible, de modo que su decisión no afecte demasiado a al usuario
del proceso en conflicto, y sobre todo que no afecte a los demás usuarios del
sistema.
Unidad 3 Administración del Procesador
3.1 Planeación Trabajos Job Scheduling
3.2 Conceptos Basicos Job Scheduling
El Job Scheduler de Adaptive Server Enterprise (ASE), incluido desde la versión
12.5.1 (12.5.2 en Windows), es un componente que permite crear y programar la
ejecución de tareas de base de datos, con el objetivo de automatizar la labores
rutinarias del administrador y sin la necesidad de utilizar herramientas externas a
ASE, como el cron de UNIX.
Conceptos
Antes de instalar y configurar el Job Scheduler de ASE, es importante definir y
entender los siguientes conceptos:

Job – Un job es una tarea de base de datos definida en términos de una
secuencia válida de comandos Transact-SQL, como por ejemplo una
serie de comandos dump o dbcc.

Schedule – Un schedule es un horario de ejecución, definido en términos
de atributos particulares, como fecha y hora de inicio, periodicidad, fecha
y hora de finalización, etc.

Scheduled Job – Un scheduled job es un job que ha sido asociado a un
schedule y que, en consecuencia, se ejecutará automáticamente de
acuerdo a lo definido en dicho schedule. La ejecución del scheduled job
se lleva a cabo en el ASE denominado Target Server.

Target Server – Es el servidor ASE en el cual se ejecutará un scheduled
job.

JS Server – Es el servidor ASE que almacena y administra los
componentes del Job Scheduler (jobs, schedules y scheduled jobs) y es
el encargado de controlar la ejecución de los scheduled jobs a través de
los JS Tasks e interactuando con el JS Agent. En este servidor reside la
base de datos sybmgmtdb en donde se almacena toda la información del
sistema del Job Scheduler.

JS Task – Es una tarea interna que corre en el ASE denominado JS
Server, encargada de determinar qué scheduled jobs deben ser
ejecutados en cada momento del tiempo. Cuando una tarea JS Task
determina que una scheduled job debe ser ejecutado, pasa la información
al JS Agent, quien inicia la ejecución en el ASE denominado Target
Server.

JS Agent – Es un proceso del sistema operativo que corre en la mísma
máquina del JS Server. El JS Agent es el encargado de controlar la
ejecución de los scheduled jobs en el Target Server, de acuerdo a la
información recibida por los JS Task.
Arquitectura del Job Scheduler
Una vez el Job Scheduler ha sido debidamente instalado y configurado en ASE (en el JS
Server), su funcionamiento se puede resumir en tres pasos básicos (la información sobre
la instalación del Job Scheduler se encuentra en la siguiente sección):
1. El usuario crea un conjunto de jobs, schedules y scheduled jobs en el JS Server. Para
cada scheduled job define también el Target Server en donde éste se ejecutará. Toda
esta información es almacenada en la base de datos sybmgmtdb del JS Server. La
creación de los jobs, schedules y scheduled jobs se puede hacer por línea de comandos
o gráficamente desde Sybase Central.
2. El JS Task, que se ejecuta internamente en el JS Server, determina cuándo se debe
ejecutar cada scheduled job y sobre cuál Target Server, leyendo información de la base
de datos sybmgmtdb; esta información es pasada al JS Agent.
3. El JS Agent ejecuta de manera automática el scheduled job en el Target Server. La
información histórica sobre la ejecución de la tarea se almacena en la base de datos
sybmgmtdb del JS Server.
Note que para efectos prácticos, el JS Server y el Target Server pueden ser el mismo
servidor ASE.
La figura 1 resume la arquitectura del JS de ASE:
Figura 1 - Arquitectura del Job Scheduler de ASE
Instalación y Cofiguración del Job Scheduler
Para poder utilizar el Job Scheduler, usted debe completar los siguientes pasos básicos.
Asumiremos para los ejemplos de ésta sección que el nombre del JS Server es PROD y
que el nombre de la máquina donde éste corre es Jupiter.
Note que en Windows usted debe reemplazar $SYBASE por %SYBASE% y
$SYBASE_ASE por %SYBASE_ASE%.
Instalación
1. En el JS Server cree un dispositivo de datos (database device) llamado sybmgmtdev,
con un tamaño mínimo de 50 Mb (ASE 12.5.x) o 75 Mb (ASE 15.x). Por ejemplo:
disk init name = "sybmgmtdev",
physname = "/home/sybase/ASE-12_5/data/sybmgmtdev.dat",
size = "75M"
go
2. Ejecute el script installjsdb:
isql -Usa -Psa_password -SPROD -i$SYBASE/$SYBASE_ASE/scripts/installjsdb
3. En la máquina donde corre el JS Server cree una entrada para el JS Agent en el archivo
$SYBASE/interfaces usando el utilitario dsedit. Una vez creada la entrada, el archivo
interfaces en Unix se vería así:
PROD_JS
master tcp ether Jupiter port_number
query tcp ether Jupiter port_number
port_number es el número de puerto asignado al JS Agent; este debe ser un puerto que no
esté ya en uso. Sybase recomienda que el nombre del JS Agent sea de la forma
servername_jsagent.
4. Use sp_addserver para crear un nuevo servidor remoto llamado SYB_JSAGENT en el
JS Server:
sp_addserver SYB_JSAGENT, null, PROD_JS
go
5. En el JS Server habilite el Job Scheduler:
sp_configure "enable job scheduler", 1
go
6. Para arrancar el Job Scheduler usted puede reiniciar ASE o ejecutar el siguiente
comando:
use sybmgmtdb
go
sp_js_wakeup "start_js", 1
go
Definición de Usuarios y Privilegios
Usted debe definir un conjuno de usuarios que puedan crear, administrar y ejecutar tareas
usando el Job Scheduler. Esos usuarios deben tener un login tanto en el JS Server como
en el Target Server.
Asumiremos para el ejemplo que hemos creado un login llamado usuario_js, tanto en el
JS Server como en el Target Server:
1. Agregue el usuario a la base de datos sybmgmtdb del JS Server:
use sybmgmtdb
go
sp_adduser usuario_js
go
2. Otorgue los privilegios adecuados al usuario:
sp_role "grant", js_user_role, usuario_js
go
sp_modifylogin usuario_js, "add default role", js_user_role
go
Usted también puede otorgar los roles js_admin_role y/o js_client_role.
Note, además, que usted debe otorgar los roles y permisos adecuados al usuario, de tal
manera que éste pueda ejecutar de manera exitosa los jobs. Por ejemplo, si el usuario va a
ejecutar una tarea que incluye un dump database, éste debe ser dueño de la base de
datos (dbo) o tener el rol oper_role, de lo contrario la ejecución de la tarea programada
fallará.
Defina el Acceso a los Servidores Remotos
Cuando el JS Server y el Target Server son Diferentes
Si usted desea programar tareas sobre el servidor ASE en donde instaló el Job Scheduler,
omita los pasos de ésta sección y haga referencia a la siguiente sección, "Cuando el JS
Server y el Target Server son el Mismo".
Cuando el JS Server y el Target Server son diferentes, usted deberá definir el acceso a los
servidores remotos o Target Servers en donde se ejecutarán las tareas programadas.
Asumiremos para el ejemplo que vamos a definir un Target Server llamado TEST el cual
reside en la máquina Venus:
1. Usando dsedit agregue una entrada al archivo interfaces de la máquina donde reside el
JS Server. Esta entrada en Unix se vería así:
TEST
master tcp ether Venus port_number
query tcp ether Venus port_number
donde port_number es el puerto del servidor ASE remoto (Target Server).
2. En el JS Server agregue un servidor remoto asociado al Target Server:
sp_addserver TEST
go
3. Agregue los logins externos para los usuarios del Job Scheduler en el JS Server:
sp_addexternlogin TEST, usuario_js, usuario_js, remote_password
go
Note que en este caso el login usuario_js existe tanto en el JS Server como en el Target
Server.
Cuando el JS Server y el Target Server son el Mismo
Si el JS Server y el Target Server son diferentes, omita los pasos de ésta sección y haga
referencia a la sección anterior, "Cuando el JS Server y el Target Server son Diferentes".
Cuando el JS Server y el Target Server son el mismo, en otras palabras usted desea
programar tareas en el servidor ASE en donde instaló el Job Scheduler, siga estos pasos:
1. En el JS Server agregue un servidor remoto llamado loopback. Por ejemplo:
sp_addserver loopback, null, PROD
go
donde PROD es el nombre del servidor local (el JS Server).
2. Agregue un login externo para el usuario del Job Scheduler en el JS Server:
sp_addexternlogin loopback, usuario_js, usuario_js, remote_password
go
Para mayor información sobre la instalación y configuración del JS por favor consulte en
manual Job Scheduler User's Guide, incluido con la documentación de ASE.
Creación y Programación de una Tarea de Base de Datos
En ésta última sección veremos paso a paso la creación de un Scheduled Job
usando Sybase Central. Para efectos del ejemplo, crearemos un job que
ejecutará un comando dump todos los días a media noche.
Conéctese al JS Server
1. Ejecute Sybase Central y conéctese al servidor ASE en donde instaló el
Job Scheduler (el JS Server). Esta conexión la puede hacer usando uno
de los usuarios definidos en la sección anterior, por ejemplo usuario_js.
2. Una vez conectado, haga doble click en la carpeta Scheduled Jobs.
Usted verá una ventana como la siguiente:
La carpeta Scheduled Jobs contiene información sobre los jobs que han sido
programados y su estado. También contiene un asistente para la programación
de nuevos jobs (Add Scheduled Job) y las carpetas Jobs, Schedules y Job
History.
La carptea Jobs contiene información sobre los jobs que han sido creados y un
asistente para la creación de nuevos jobs; la carpeta Schedules contiene
información sobre los schedules que han sido creados y un asistente para la
creación de nuevos schedules y la carpeta Job History contiene información
histórica sobre la ejecución de las tareas programadas.
Cree un Job
1. Haga doble click sobre la carpeta Jobs y luego sobre el ícono Add Job.
En éste momento se ejecutará un asistente que lo guiará en la creación
del Job.
2. Escriba el nombre del job, por ejemplo dump_master y luego haga click
en Next.
3. Escriba la descripción, por ejemplo Dump de master y luego haga click
en Next.
4. Escriba la definición del job. Por ejemplo:
dump database master
to "D:\Sybase\dumps\master.dmp"
Recuerde que la definición del job se debe hacer en términos de una secuencia
válida de comandos Transact-SQL. Para este caso además, usted se debe
asegurar de que la ruta del archivo sea válida en el Target Server. Haga click en
Next.
5. En la siguiente ventana defina los atributos adicionales del job y luego
haga click en Next (puede dejar los valores predeterminados).
6. En la siguiente ventana defina el timeout y luego haga click en Next
(puede dejar el valor predeterminado).
7. En la última ventana usted verá un resumen de su nuevo job; haga click
en Finish. Usted verá su nuevo job en la carpeta Jobs:
Usted puede cambiar cualquiera de las propiedades del job haciendo click
derecho sobre éste y seleccionando el ítem Properties del menú desplegable.
Cree un Schedule
1. Haga doble click en la carpeta Schedules y luego en el ícono Add
Schedule. En este momento se ejecutará un asistente que lo guiará en la
creación del schedule.
2. Especifique el nombre del schedule, por ejemplo todos_los_dias_12am
y luego haga click en Next.
3. Escriba una descripción para el schedule, por ejemplo Todos los dias a
la media noche y luego haga clock en Next.
4. Defina la hora o rango de horas. Para este caso seleccionaremos la
opción At y la hora 00:00. Haga click en Next.
5. Seleccione la fecha de inicio y haga click en Next.
6. Selecionee la fecha de finalización o No end date si no hay fecha de
finalización; haga click en Next.
7. Defina otras características del schedule y luego haga click en Next.
8. La última ventana mostrará un resumen de su nuevo schedule; haga click
en Finish. Usted verá su nuevo schedule en la carpeta Schedules:
Usted puede cambiar cualquiera de las propiedades del schedule haciendo click
derecho sobre éste y seleccionando el ítem Properties del menú desplegable.
Programe su Job (Creee un Scheduled Job)
Una vez creado el job y el schedule, usted puede programar su job para que se
ejecute en el horario especificado por el schedule.
Una forma de hacerlo es:
1. Haga doble click en la carpeta Jobs.
2. Haga click derecho sobre el job recién creado; del menú desplegable
seleccione el ítem Schedule. En este momento se ejecutará el asistente
que le permitirá programar dicho job.
3. Confirme que el nombre del job es el que usted desea programar y
presione Next.
4. En la siguiente ventana seleccione de la lista el nombre del schedule que
usted desea usar, por ejemplo todos_los_dias_12am; haga click en
Next.
5. Seleccione de la lista el Target Server que desea utilizar; este es el
nombre del ASE en donde se ejecutará la tarea programada o scheduled
job. Haga click en Next.
6. Defina atributos adicionales del scheduled job y presione Next.
7. En la siguiente ventana defina las opciones de "post-ejecución" y luego
haga click en Next.
8. En la última ventana aparecerá un resumen de su nuevo Scheduled Job.
Para terminar haga click en Finish. En la carpeta Scheduled Jobs usted
verá su nueva tarea programada:
Una vez creado el Scheduled Job éste comenzará a ejecutarse de acuerdo al
horario definido por el schedule. Usted tambíén puede probar su ejecución
haciendo click derecho sobre el scheduled job y seleccionando el ítem Run Now
del menú desplegable:
También es posible cambiar cualquiera de las propiedades del scheduled job
haciendo click derecho sobre éste y seleccionando el ítem Properties del menú
desplegable.
Solución a Problemas
Log de los scheduled jobs
En la carpeta Job History (bajo Scheduled Jobs) usted encontrará la
información sobre el estado de los scheduled jobs que se han ejecutado. Al dar
click derecho sobre cualquiera de los ítems, usted verá varias opciones, entre
las que se destaca la opción View Log. Esta opción le permite ver la salida
generada durante la ejecución de la tarea.
Log de errores del JS Agent
También puede encontrar información adicional sobre los scheduled jobs en el
log de errores de ASE y en el log de errores del JS Agent, usualmente ubicado
en $SYBASE/$SYBASE_ASE/install/servername.log (donde servername es el
nombre del JS Agent, por ejemplo PROD_JS.log).
3.3 Tipos de Planeacion Job Scheduling
PLANEACION DE TRABAJOS (JOB SCHEDULING)
Objetivo de la planificación: Minimizar el tiempo de espera y minimizar el tiempo
de respuesta. La planificación (scheduling) es la base para lograr la
multiprogramación.
Un sistema multiprogramado tendrá varios procesos que requerirán el recurso
procesador a la vez. Esto sucede cuando los procesos están en estado ready
(pronto). Si existe un procesador disponible, se debe elegir el proceso que será
asignado para ejecutar. La parte del sistema operativo que realiza la elección del
proceso es llamada planificador (scheduler).
La planificación hace referencia a un conjunto de políticas Y mecanismos
incorporados a sistemas operativos que gobiernan el orden en que se ejecutan
los trabajos.
Un planificador es un módulo del S.O que selecciona el siguiente trabajo que
hay que admitir en el sistema y el siguiente proceso que hay que ejecutar
En muchos sistemas, la actividad de planificación se divide en tres funciones
independientes: planificación a largo, medio, y corto plazo.
3.3.1 First in First Out Job Scheduling (FIFO)
FIRST IN FIRST OUT (FIFO) Es muy simple, los procesos se despachan de
acuerdo con su tiempo de llegada a la cola de listos. Una vez que el proceso
obtiene la cpu, se ejecuta hasta terminar, ya que es una disciplina “no
apropiativa”. Puede ocasionar que procesos largos hagan esperar a procesos
cortos y que procesos no importantes hagan esperar a procesos importantes. Es
más predecible que otros esquemas. No puede garantizar buenos tiempos de
respuesta interactivos. Suele utilizarse integrado a otros esquemas, por ejemplo,
de la siguiente manera: • Los procesos se despachan con algún esquema de
prioridad. • Los procesos con igual prioridad se despachan “FIFO”.
3.3.2 Round Robin Job Scheduling (RR)
ROUN ROBIN (RR) Algoritmo apropiativo consistente en determinar un quantum
(tiempo de reloj) que marcará el intervalo de CPU que se le cederá al proceso
ejecutando. Cuando finalice el quantum al Proceso se le quitará la CPU y pasará
a la cola de listo. La cola de listos sigue la estructura FIFO. Si un proceso no
consume su quantum libera la CPU y ésta es asignada al siguiente Proceso de
la cola de listo.
Los procesos se despachan en “FIFO” y disponen de una cantidad limitada de
tiempo de cpu, llamada “división de tiempo” o “cuanto”. Si un proceso no termina
antes de expirar su tiempo de cpu ocurren las siguientes acciones: 1. La cpu es
apropiada. 2. La cpu es otorgada al siguiente proceso en espera. 3. El proceso
apropiado es situado al final de la lista de listos. Es efectiva en ambientes de
tiempo compartido. La sobrecarga de la apropiación se mantiene baja mediante
mecanismos eficientes de intercambio de contexto y con suficiente memoria
principal para los procesos. Características: • Fácil de implementar. • Perjudica a
los procesos de E/S. • Si el quantum es muy grande se comporta como un
FCFS. • El tiempo de respuesta para procesos cortos es bueno. • Trato
equitativo entre procesos, bueno para interactividad. • No se produce inanición. •
El valor mínimo del quantum debe ser (10 * Tiempo Cambio Contexto ) • El
quantum más adecuado es el Tiempo de CPU del proceso más corto.
3.3.3 Shortest Job First Job Scheduling (SJF)
SHORTEST JOB FIRST (SJF) Es una disciplina no apropiativa y por lo tanto no
recomendable en ambientes de tiempo compartido. El proceso en espera con el
menor tiempo estimado de ejecución hasta su terminación es el siguiente en
ejecutarse. Los tiempos promedio de espera son menores que con “FIFO”. Los
tiempos de espera son menos predecibles que en “FIFO”. Favorece a los
procesos cortos en detrimento de los largos. Tiende a reducir el número de
procesos en espera y el número de procesos que esperan detrás de procesos
largos. Requiere un conocimiento preciso del tiempo de ejecución de un
proceso, lo que generalmente se desconoce. Se pueden estimar los tiempos en
base a series de valores anteriores.
3.3.4 Shortest Remaining Time Job Scheduling (STR)
SHORTEST REMAINING TIME (STR) Esta disciplina elige siempre al proceso
que le queda menos tiempo de ejecución estimado para completar su ejecución;
de esta forma aunque un proceso requiera mucho tiempo de ejecución, a
medida que se va ejecutando iría avanzando en la lista de procesos en estado
listo hasta llegar a ser el primero. Para realizar esta elección, es necesario
actualizar el PCB de los procesos a medida que se le asigna tiempo de servicio,
lo que supone una mayor sobrecarga adicional. Es una disciplina apropiativa ya
que a un proceso activo se le puede retirar la CPU si llega a la lista de procesos
en estado listo otro con un tiempo restante de ejecución estimado menor. Este
algoritmo es la versión no apropiativa o espulsiva del algoritmo Shortest Process
Next (SPN) o también llamado Shortest Job First (SJF). En el algoritmo Shortest
Remaining Time el planificador selecciona el proceso más corto, al igual que
antes, pero en este caso el cambio se controla cada vez que un proceso llega a
la cola. Es decir, cuando un proceso se desbloquea o se crea uno nuevo y el
tiempo de ráfaga es menor que el tiempo de ráfaga del proceso que se está
ejecutando, entonces se realiza un cambio de contexto, el bloqueado se ejecuta
y el que se estaba ejecutando pasa a la cola de procesos listos. De este modo
cuando se desbloquea o entra un proceso nuevo, se calcula su tiempo de
ráfaga. Si el proceso que se está ejecutando le queda más tiempo de ráfaga que
nuestro tiempo de ráfaga calculado entonces se procede a realizar el cambio de
contexto. . Definición: Algoritmo apropiativo (que en cualquier momento se le
puede quitar la CPU para asignársela otro proceso) consistente en elegir de la
cola de listos el proceso con menos necesidad de tiempo restante de CPU para
cada instante de tiempo.
Características:
Ofrece un buen tiempo de respuesta.
La productividad es alta a cambio de la sobrecarga del sistema (a cada paso
debe decidir a que proceso asignarle la CPU).
Penaliza los procesos largos.
Se puede producir inanición.
3.3.5 Highest Response Ratio Next Job Scheduling (HNR)
HIGHEST RESPONSE RATIO NEXT (HRN) Definición: Algoritmo apropiativo
parecido al SRT consistente en calcular el Reponse Ratio (Ratio de respuesta)
para asignar la CPU a procesos más viejos. (Para evitar la inanición).
Características:
Es muy productivo pero se sobrecarga el sistema.
Ofrece un buen tiempo de respuesta.
Equilibra los procesos, aunque da prioridad a los procesos más cortos.
Evita la inanición (los procesos que envejecen serán ejecutados).
Las prioridades, que son dinámicas, se calculan según la siguiente fórmula,
donde pr es la “prioridad”, te es el “tiempo de espera” y ts es el “tiempo de
servicio”: • Elige proceso listo con valor mayor de R • Tiene en cuenta edad del
proceso • Debe estimarse el tiempo se servicio previamente: en base a historia
pasada o valor dado por usuario o administrador. • R= w + s
s
R= tasa de respuesta w= tiempo consumido esperando al procesador s = tiempo
de servicio esperado Que corrige algunas deficiencias de SJF, particularmente el
retraso excesivo de trabajos largos y el favoritismo excesivo para los trabajos
cortos. HRN es un disciplina de planificación no apropiativa en la cual la
prioridad de cada proceso no sólo se calcula en función del tiempo de servicio,
sino también del tiempo que ha esperado para ser atendido. Cuando un trabajo
obtiene el procesador, se ejecuta hasta terminar. Las prioridades dinámicas en
HRN se calculan de acuerdo con la siguiente expresión: Prioridad = (tiempo de
espera + tiempo de servicio) / tiempo de servicio Como el tiempo de servicio
aparece en el denominador, los procesos cortos tendrán preferencia. Pero como
el tiempo de espera aparece en el numerador, los procesos largos que han
esperado también tendrán un trato favorable. Obsérvese que la suma tiempo de
espera + tiempo de servicio es el tiempo de respuesta del sistema para el
proceso si éste se inicia de inmediato. Para cada proceso, basado en el tiempo
que va a ocupar el procesador(s) y el tiempo que lleva esperando para ocuparlo
(w), Se calcula w+s/s, una vez echo esto el proceso que tenga un valor mayor
será asignado al procesador. Este algoritmo es bastante bueno, por que además
de dar preferencia a los procesos cortos también tiene en cuenta el
envejecimiento de los procesos para evitar así la “inanición”. Cuando el proceso
actual termina o se bloquea, se elige el proceso listo con un mayor valor de R.
La decisión de planificación se basa en una estimación del tiempo de retorno
normalizado. Este método es atractivo porque tiene en cuenta la edad del
proceso. Aunque se favorece a los trabajos más cortos (un denominador menor
produce una razón mayor), el envejecimiento de un proceso sin que haya sido
servido incrementa el valor de la razón, de forma que los procesos más largos
puedan pasar, en competición con los más cortos. El tiempo esperado de
servicio debe estimarse antes de emplear la técnica de la mayor tasa de
respuesta.7
3.4 Multiprocesamiento Procesador
MULTIPROCESAMIENTO
Generalidades
de
Multiprocesadores.
Un
multiprocesador se define como una computadora que contiene dos o más
unidades de procesamiento que trabajan sobre una memoria común bajo un
control integrado. Si el sistema de multiprocesamiento posee procesadores de
aproximadamente igual capacidad, estamos en presencia de multiprocesamiento
simétrico; en el otro caso hablamos de multiprocesamiento asimétrico.
Si un procesador falla, los restantes continúan operando, lo cual no es
automático y requiere de un diseño cuidadoso. Un procesador que falla habrá de
informarlo a los demás de alguna manera, para que se hagan cargo de su
trabajo . Los procesadores en funcionamiento deben poder detectar el fallo de
un procesador Determinado. El Sistema Operativo debe percibir que ha fallado
un procesador determinado y ya no podrá asignarlo y también debe ajustar sus
estrategias de asignación de recursos para evitar la sobrecarga del sistema que
está degradado.
Distribución de Ciclos Una “estructura de ciclos o de repetición” implica la
repetición de una serie de proposiciones (cuerpo del ciclo) hasta que ocurre
alguna condición de terminación, por ejemplo: For i = 1 to 3 Do
El procesador secuencial realizará en secuencia lo siguiente:
En un sistema de multiprocesamiento con tres procesadores disponibles se
podrían Ejecutar concurrentemente.
Reducción de la Altura del Arbol Utilizando las propiedades asociativa,
conmutativa y distributiva de la aritmética, los Compiladores pueden: 1. Detectar
el paralelismo implícito en expresiones algebraicas. 2. Producir un código objeto
para multiprocesadores que indique las operaciones que se pueden realizar
simultáneamente. 3. Reordenar expresiones para que sean más apropiadas
para la computación en paralelo.
3.5 Conceptos Basicos Multiprocesamiento
SISTEMAS MULTIPROCESAMIENTO INTRODUCCION A pesar de las grandes
mejoras acaecidas en monoprocesadores para algunas aplicaciones no es
suficiente. – La solución pueden ser los sistemas multiprocesadores: o Solución
más sencilla, natural y con mejor coste-prestaciones. o Las mejoras en
microprocesadores cada vez son más complejas: cada avance implica crecer en
complejidad, potencia y superficie. o Lenta pero clara mejora en el software, que
permite explotar el paralelismo. – Las arquitecturas actuales son muy diversas:
hay más investigación que resultados definitivos. – Hablaremos de
multiprocesadores de pequeña y median escala
Dos factores clave para la extensión de los Multiprocesadores 1. Flexibilidad: El
mismo sistema puede usarse para un único usuario incrementado el rendimiento
en la ejecución de una única aplicación o para varios usuarios y aplicaciones en
un entorno compartido. 2. Coste-rendimiento: Actualmente estos sistemas se
basan en procesadores comerciales, por lo que su coste se ha reducido
drásticamente. La inversión más fuerte se hace en la memoria y la red de
interconexión.
Como su nombre indica son aquellos sistemas operativos que están
montados sobre ordenadores que están compuestos por más de un procesador,
supongamos un PC que en vez de tener un Pentium, tuviera dos o más Pentium
conectados entre si dentro de la misma placa base, esto sería un sistema
multiprocesador.
CLASIFICACION POR USO DE LOS RECURSOS Sistemas monoprogramados:
Son los que solo permiten la ejecución de un programa en el sistema, se instalan
en la memoria y permanecen allí hasta que termine su ejecución. Sistemas
multiprogramados: Son aquellos que se basan en las técnicas de
multiprogramación, existen dos tipos:

Multitarea apropiativa (preemptive): Se utiliza en sistemas operativos cuya
gestión es quitar el control del microprocesador al programa que lo tiene.
 Multitarea cooperativa: El programa tiene el control del microprocesador,
el sistema operativo no puede decidir quien usa el microprocesador.
Sistemas de multiprocesamiento: Formado por varios microprocesadores.
Depende del tipo de trabajo y los objetivos que debe cumplir cada sistema para
dar el mejor servicio al usuario, se clasifican en: Procesamiento por lotes (batch):
Cada programa realiza un conjunto de pasos secuenciales relacionados entre s
3.6 Paralelismo Multiprocesamiento
PARALELISMO Funcionamiento El paralelismo consiste en ejecutar más
instrucciones en menos tiempo, aunque las instrucciones sigan tardando lo
mismo en ejecutarse, mediante un simple truco, aunque algo difícil de explicar
en detalle. Intentémoslo. un microprocesador ejecuta instrucciones de código
máquina. Estas instrucciones le dicen como tiene que ir modificando diferentes
posiciones de memoria, y como debe ir modificando el flujo de ejecución. Se
tiende a pensar, erróneamente, que un procesador con un reloj a 200 MHz (200
millones de ciclos por segundo) ejecuta 200 millones de estas operaciones por
segundo. Esto no es así, por una sencilla razón. Una instrucción no se ejecuta
en un solo ciclo de reloj, salvo alguna rara excepción. De hecho, algunas
instrucciones tardan bastantes más ciclos, llegando algunas a necesitar 50 o
más ciclos para completarse. En cambio, las más rápidas se ejecutan en tan
sólo 3 o 4 ciclos de reloj. Aquí es donde entra el paralelismo para solucionar este
problema. Se puede dividir cualquier instrucción en fases más o menos comunes
a todas: fetch (carga de la instrucción desde la memoria al procesador),
decodificación (identificación de qué instrucción nos hemos encontrado), carga
de operandos, operación en sí y escritura de resultados. Este esquema,
expresamente simplificado, nos da una idea de las fases que todo
microprocesador tiene. Vamos a suponer un microprocesador ideal donde todas
las operaciones que se pueden ejecutar en él tardan 15 ciclos, correspondientes
a tres ciclos por cada una de las 5 fases que hemos descrito. Si ejecutáramos
tres de estas operaciones sin ningún tipo de paralelismo, tardaríamos 45 ciclos,
según
el
siguiente
esquema:
instr.1:111222333444555
instr.2:
111222333444555 instr. 3: 111222333444555 Ahora supongamos que somos
capaces de dividir el microprocesador en circuitos separados capaces cada uno
de trabajar independientemente y ejecutar cada una de las 5 fases anteriores. Si
logramos que sean independientes, cuando la instrucción uno ha acabado ya la
fase de fetch y pasa a la decodificación, deja libre el módulo que se encarga del
fetch, donde puede ir ya ejecutándose la segunda instrucción. De esta forma,
logramos paralelizar las instrucciones. instr.1111222333444555 instr.2:
111222333444555 instr. 3: 111222333444555 Resultado: las tres instrucciones,
por separado, siguen ejecutándose en el mismo tiempo, pero en conjunto ya no
tardan 45 ciclos, sino solo 21 ciclos. Más de un 45% de incremento en el
rendimiento. De esta forma es como algunos procesadores muy paralelizados
logran ejecutar, en media, más de una instrucción por ciclo de reloj, aunque
estas instrucciones tarden, por sí mismas, más de un ciclo en ejecutarse. En la
realidad, como siempre, no todo es tan fácil y hay muchos problemas al diseñar
un procesador con paralelismo. Por citar algunos de los problemas más
comunes, hay veces que una instrucción no se puede ejecutar ya que requiere
un dato que quizás calculaba la operación anterior (cosa muy habitual). Claro, si
ante este problema detuviéramos la anterior instrucción, bloquearía el
procesador y se acabaría el paralelismo hasta que acabara la primera
instrucción y con ella se pudiera reanudar la segunda. Para evitar estos
problemas se recurre a cortocircuitos, o lo que es lo mismo, se comunican
diferentes fases del microprocesador internamente para pasarse antes los datos.
Esto, sin embargo, también nos da otros problemas, ya mucho más
complicados, como el encontrarnos con que hay que decidir que datos son los
correctos en cada momento. En estos problemas ya no entraremos, y se podrían
resumir en que el procesador ha de decidir como paralelizar las instrucciones.
Bien, todo lo que hemos visto sobre el paralelismo involucra única y
exclusivamente al microprocesador en sí, y más bien a su diseño. El software
que se ejecuta sobre él ignora totalmente si hay paralelismo o no. Esto es el
paralelismo implícito. Por el contrario, Intel implementa una solución que de
hecho ya deriva de ideas de principios de los años 80. En el paralelismo
explícito, el procesador ya no es el que decide cómo paralelizar las
instrucciones, sino que es el compilador del software el que ha empaquetado las
instrucciones para que el microprocesador pueda ejecutarlas paralelamente sin
tantos problemas. De hecho, esta manera es mucho más eficiente, porque el
compilador tiene todo el tiempo del mundo para decidir cómo paralelizar y por
supuesto, la lógica que puede aplicar es infinitamente más potente que la que
podemos encontrar implementada en cualquier microprocesador. Esto también
redunda en una simplificación de la circuitería de control del microprocesador, lo
que permite acelerar aún más las instrucciones. Además, queda libre más
espacio para incluir aún más registros y hacer los buses internos más anchos, lo
que permite ejecutar aún más instrucciones en paralelo. Paralelismo en software
Definamos como paralelismo en software como la ejecución de un programa sin
tomar en cuenta el hardware con que va ser ejecutado. El paralelismo en
software es considerado como el caso ideal de la ejecución de las instrucciones
que forman parte de un programa, ya que no toma en cuenta las limitantes del
hardware con que el mismo va ser ejecutado. Paralelismo en hardware
Definamos como paralelismo en hardware como la ejecución de un programa
tomando en consideración el hardware con que va a ser ejecutado. El diagrama
de paralelismo en Software representa el caso ideal con que dicho programa
puede ser ejecutado. Nótese que la ejecución de las 8 instrucciones se realiza
solamente en tres ciclos de máquina. Por otro lado podemos observar las
limitantes que genera la ejecución de este mismo programa con un hardware en
particular (procesador Superescalar con capacidad de ejecutar un acceso a la
memoria y una operación aritmética simultáneamente) obteniendo 6 ciclos de
maquina para ejecutar el programa. Tomando como base este ejemplo, la
ejecución paralela de las instrucciones de un programa se mide mediante el
parámetro conocido como Promedio de Ejecución Paralela de instrucciones
(PEP). Este parámetro se define como la relación entre el número de
instrucciones del programa y el número de ciclos de máquina realizados en su
ejecución. Su expresión matemática es: PEP = No. de Instrucciones / No. de
Ciclos de Máquina Por consiguiente, el promedio de ejecución paralela de
instrucciones en software para este ejemplo es: 8/3 = 2,667 y el promedio de
ejecución paralela de instrucciones en hardware es: 8/6 = 1,333. El desarrollo de
hardware y software es un proceso integral que busca soluciones que permitan
satisfacer cada vez más las condiciones de paralelismo con el fin de incrementar
el promedio de ejecución paralela de instrucciones. Para lograr este objetivo es
necesario detectar y resolver las dependencias entre instrucciones. El proceso
de detección y resolución de dependencias entre instrucciones se conoce como
el proceso de planificación de instrucciones. Cuando la planificación de
instrucciones es llevada a cabo únicamente por el compilador se dice que la
planificación de instrucciones es estática. Y cuando la planificación de
instrucciones es llevada a cabo únicamente por hardware (Ejemplo:
microprocesador) se dice que la planificación de instrucciones es dinámica. La
planificación de instrucciones en los microprocesadores súper escalares es un
proceso de planificación de instrucciones estático y dinámico. Las técnicas
estáticas de planificación de instrucciones están compuestas por tres grupos:
Planificación de instrucciones de bloques de un programa, Planificación de
instrucciones de lazos iterativos continuos y planificación de instrucciones global.
La técnica de bloques consiste en dividir un programa en bloques para luego
detectar y resolver solamente las dependencias entre las instrucciones de cada
bloque. Esta técnica es la mas utilizada en los últimos 20 años ya que es la más
simple de implementar. La técnica de lazos iterativos consiste planificar las
instrucciones que forman parte de los lazos continuos de un programa. Esta
técnica esta compuesta básicamente por dos técnicas: Unrolling y Software
Pipeline. Y por ultimo la técnica global consiste en planificar todas las
instrucciones que forman parte de un programa. En la sección 2 del seminario
Arquitectura de Microprocesadores se analizan las técnicas más comunes de
planificación
de
instrucciones
dinámicas
implementadas
en
los
microprocesadores y a su vez se demuestra que el desarrollo de hardware y
software es un proceso integral que busca soluciones que permitan satisfacer
cada vez más las condiciones de paralelismo con el fin de incrementar el
promedio de ejecución paralela de instrucciones.
3.7 Sistemas Multiprocesamiento
SISTEMAS MULTIPROCESAMIENTO INTRODUCCION
A pesar de las grandes mejoras acaecidas en monoprocesadores para algunas
aplicaciones no es suficiente.
– La solución pueden ser los sistemas multiprocesadores:
o Solución más sencilla, natural y con mejor coste-prestaciones.
o Las mejoras en microprocesadores cada vez son más complejas: cada avance
implica crecer en complejidad, potencia y superficie.
o Lenta pero clara mejora en el software, que permite explotar el paralelismo.
– Las arquitecturas actuales son muy diversas: hay más investigación que
resultados definitivos.
– Hablaremos de multiprocesadores de pequeña y median escala
Dos factores clave para la extensión de los Multiprocesadores
1. Flexibilidad: El mismo sistema puede usarse para un único usuario
incrementado el rendimiento en la ejecución de una única aplicación o para
varios usuarios y aplicaciones en un entorno compartido.
2. Coste-rendimiento: Actualmente estos sistemas se basan en procesadores
comerciales, por lo que su coste se ha reducido drásticamente. La inversión más
fuerte se hace en la memoria y la red de interconexión.
Como su nombre indica son aquellos sistemas operativos que están montados
sobre ordenadores que están compuestos por más de un procesador,
supongamos un PC que en vez de tener un Pentium, tuviera dos o más Pentium
conectados entre si dentro de la misma placa base, esto sería un sistema
multiprocesador.
CLASIFICACION POR USO DE LOS RECURSOS
Sistemas monoprogramados: Son los que solo permiten la ejecución de un
programa en el sistema, se instalan en la memoria y permanecen allí hasta que
termine su ejecución.
Sistemas multiprogramados: Son aquellos que se basan en las técnicas de
multiprogramación, existen dos tipos:

Multitarea apropiativa (preemptive): Se utiliza en sistemas operativos cuya
gestión es quitar el control del microprocesador al programa que lo tiene.
 Multitarea cooperativa: El programa tiene el control del microprocesador,
el sistema operativo no puede decidir quien usa el microprocesador.
Sistemas de multiprocesamiento: Formado por varios microprocesadores.
Depende del tipo de trabajo y los objetivos que debe cumplir cada sistema para
dar el mejor servicio al usuario, se clasifican en:
Procesamiento por lotes (batch): Cada programa realiza un conjunto de pasos
secuenciales relacionados entre si
3.8 Organizacion del Multiprocesador
ORGANIZACIÓN DEL HARDWARE DEL MULTIPROCESADOR El problema
clave es determinar los medios de conexión de los procesadores múltiples y los
procesadores de Entrada / Salida a las unidades de almacenamiento.
Los multiprocesadores se caracterizan por los siguientes aspectos: • Un
multiprocesador contiene dos o más procesadores con capacidades
aproximadamente comparables. • Todos los procesadores comparten el acceso
a un almacenamiento común y a canales de Entrada / Salida, unidades de
control y dispositivos. • Todo está controlado por un Sistema Operativo que
proporciona interacción entre procesadores y sus programas en los niveles de
trabajo, tarea, paso, archivo y elementos de datos. Las organizaciones más
comunes son las siguientes: • Tiempo compartido o bus común (conductor
común). • Matriz de barras cruzadas e interruptores. • Almacenamiento de
interconexión múltiple. Tiempo Compartido o Bus Común (o Conductor Común)
Usa un solo camino de comunicación entre todas las unidades funcionales
El bus común es en esencia una unidad pasiva. Un procesador o procesador de
Entrada / Salida que desee transferir datos debe efectuar los siguientes pasos:
1. Verificar la disponibilidad del conductor y de la unidad de destino. 2. Informar
a la unidad de destino de lo que se va a hacer con los datos. 3. Iniciar la
transferencia de datos. Las unidades receptoras deben poder reconocer qué
mensajes del bus son enviados hacia ellas y seguir y confirmar las señales de
control recibidas de la unidad emisora. Es una organización económica, simple y
flexible pero con una sola vía de comunicación, por lo cual: • El sistema falla
totalmente si falla el bus. • La tasa neta de transmisiones está limitada por la
tasa neta de transmisión del conductor. • La contención por el uso del bus en un
sistema sobrecargado puede ocasionar una seria degradación. Matriz de Barras
Cruzadas e Interruptores En este caso existe un camino diferente para cada
unidad de almacenamiento, por lo cual las referencias a dos unidades diferentes
de almacenamiento no son bloque antes sino simultáneas y la multiplicidad de
caminos de transmisión puede proporcionar tasas de transferencia muy altas
Almacenamiento de Interconexión Múltiple Se obtiene al sacar las lógicas de
control, de conmutación y de arbitraje de prioridades fuera del interruptor de
barras cruzadas se las coloca en la interfaz de cada unidad de almacenamiento
Cada unidad funcional puede acceder a cada unidad de almacenamiento, pero
sólo en una “conexión de almacenamiento” específica, es decir que hay una
conexión de almacenamiento por unidad funcional. El conexionado es más
complejo que en los otros esquemas. Se puede restringir el acceso a las
unidades de almacenamiento para que no todas las unidades de procesamiento
las accedan, en tal caso habrá unidades de almacenamiento “privadas” de
determinados procesadores
3.9 Sistemas Operativos del Multiprocesador
Sistema Operativo de Multiprocesadores Las capacidades funcionales de los
Sistema Operativo de multiprogramación y de multiprocesadores incluyen lo
siguiente: • Asignación y administración de recursos. • Protección de tablas y
conjuntos de datos. • Prevención contra el ínter bloqueo del sistema. •
Terminación anormal. • Equilibrio de cargas de Entrada / Salida. • Equilibrio de
carga del procesador. • Reconfiguración. Las tres últimas son especialmente
importantes en Sistemas Operativos de multiprocesadores, donde es
fundamental explotar el paralelismo en el hardware y en los programas y hacerlo
automáticamente. Las organizaciones básicas de los Sistemas Operativos para
multiprocesadores son las siguientes: • Maestro / satélite. • Ejecutivo separado
para cada procesador. • Tratamiento simétrico (o anónimo) para todos los
procesadores. Maestro / Satélite Es la organización más fácil de implementar.
No logra la utilización óptima del hardware dado que sólo el procesador maestro
puede ejecutar el Sistema Operativo y el procesador satélite sólo puede ejecutar
programas del usuario. Las interrupciones generadas por los procesos en
ejecución en los procesadores satélites que precisan atención del Sistema
Operativo deben ser atendidas por el procesador maestro y por ello pueden
generarse largas colas de requerimientos pendientes. Ejecutivos Separados
Cada procesador tiene su propio Sistema Operativo y responde a interrupciones
de los usuarios que operan en ese procesador. Existen tablas de control con
información global de todo el sistema (por ejemplo, lista de procesadores
conocidos por el Sistema Operativo) a las que se debe acceder utilizando
exclusión mutua. Es más confiable que la organización maestro / satélite. Cada
procesador controla sus propios recursos dedicados. La reconfiguración de los
dispositivos de Entrada / Salida puede implicar el cambio de dispositivos a
diferentes procesadores con distintos Sistemas Operativos. La contención sobre
las tablas del Sistema Operativo es mínima. Los procesadores no cooperan en
la ejecución de un proceso individual, que habrá sido asignado a uno de ellos.
Tratamiento Simétrico Es la organización más complicada de implementar y
también la más poderosa y confiable. El Sistema Operativo administra un grupo
de procesadores idénticos, donde cualquiera puede utilizar cualquier dispositivo
de Entrada / Salida y cualquiera puede referenciar a cualquier unidad de
almacenamiento. El Sistema Operativo precisa código reentrarte y exclusión
mutua. Es posible equilibrar la carga de trabajo más precisamente que en las
otras organizaciones. Adquieren significativa importancia el hardware y el
software para resolución de conflictos. Todos los procesadores pueden cooperar
en la ejecución de un proceso determinado. El procesador ejecutivo es el
responsable (uno sólo) en un momento dado de las tablas y funciones del
sistema; así se evitan los conflictos sobre la información global.
Unidad 4 Administración de la Memoria
4.1 Gestión de Memoria
La memoria es uno de los principales recursos de la computadora, la cual debe de
administrarse con mucho
cuidado. Aunque actualmente la mayoría de los sistemas de cómputo cuentan con una
alta capacidad de
memoria, de igual manera las aplicaciones actuales tienen también altos
requerimientos de memoria, lo que
sigue generando escasez de memoria en los sistemas multitarea y/o multiusuario.
La parte del sistema operativo que administra la memoria se llama administrador de
memoria y su labor
consiste en llevar un registro de las partes de memoria que se estén utilizando y
aquellas que no, con el fin
de asignar espacio en memoria a los procesos cuando éstos la necesiten y liberándola
cuando terminen, así
como administrar el intercambio entre la memoria principal y el disco en los casos en
los que la memoria
principal no le pueda dar capacidad a todos los procesos que tienen necesidad de ella.
Los sistemas de administración de memoria se pueden clasificar en dos tipos: los que
desplazan los
procesos de la memoria principal al disco y viceversa durante la ejecución y los que
no.
El propósito principal de una computadora es el de ejecutar programas, estos
programas, junto con la
información que accesan deben de estar en la memoria principal (al menos
parcialmente) durante la
ejecución.
Para optimizar el uso del CPU y de la memoria, el sistema operativo debe de tener
varios procesos a la vez
en la memoria principal, para lo cual dispone de varias opciones de administración
tanto del procesador
como de la memoria. La selección de uno de ellos depende principalmente del diseño
del hardware para el
sistema. A continuación se observarán los puntos correspondientes a la administración
de la memoria.
Memoria real
La memoria real o principal es en donde son ejecutados los programas y procesos de
una computadora y es
el espacio real que existe en memoria para que se ejecuten los procesos. Por lo
general esta memoria es de
mayor costo que la memoria secundaria, pero el acceso a la información contenida en
ella es de más rápido
acceso. Solo la memoria cache es más rápida que la principal, pero su costo es a su
vez mayor.
Memoria virtual
El termino memoria virtual se asocia a dos conceptos que normalmente a parecen
unidos:
1.
El uso de almacenamiento secundario para ofrecer al conjunto de las aplicaciones la
ilusión de tener
mas memoria RAM de la que realmente hay en el sistema. Esta ilusión de existe tanto
a nivel del sistema,
es decir, teniendo en ejecución mas aplicaciones de las que realmente caben en la
memoria principal, sin
que por ello cada aplicación individual pueda usar mas memoria de la que realmente
hay o incluso de forma
mas general, ofreciendo a cada aplicación mas memoria de la que existe físicamente
en la maquina.
2.
Ofrecer a las aplicaciones la ilusión de que están solas en el sistema, y que por lo
tanto, pueden usar el
espacio de direcciones completo. Esta técnica facilita enormemente la generación de
código, puesto que el
compilador no tiene porque preocuparse sobre dónde residirá la aplicación cuando se
ejecute.
Espacio De Direcciones
Los espacios de direcciones involucrados en el manejo de la memoria son de tres
tipos:
Direcciones físicas: son aquellas que referencian alguna posición en la memoria
física.
Direcciones lógicas : son las direcciones utilizadas por los procesos. Sufren una serie
de
transformaciones , realizadas por el procesador (la MMU), antes de convertirse en
direcciones físicas.
Direcciones lineales: direcciones lineales se obtienen a partir de direcciones lógicas
tras haber aplicado
una transformación dependiente de la arquitectura.
Los programas de usuario siempre tratan con direcciones virtuales ; nunca ven las
direcciones físicas
reales..
Unidad De Manejo De Memoria
La unidad de manejo de memoria (MMU) es parte del procesador. Sus funciones son:
Convertir las direcciones lógicas emitidas por los procesos en direcciones físicas.
Comprobar que la conversión se puede realizar. La dirección lógica podría no tener
un dirección física
asociada. Por ejemplo, la pagina correspondiente a una dirección se puede haber
trasladado a una zona de
almacenamiento secundario temporalmente.
Comprobar que el proceso que intenta acceder a una cierta dirección de memoria tiene
permisos para
ello.
La MMU se Inicializa para cada proceso del sistema. Esto permite que cada proceso
pueda usar el
rango completo de direcciones lógicas (memoria virtual), ya que las conversiones de
estas direcciones
serán distintas para cada proceso.
En todos los procesos se configura la MMU para que la zona del núcleo solo se pueda
acceder en
modo privilegiado del procesador.
La configuración correspondiente al espacio de memoria del núcleo es idéntica en
todos los procesos.
El objetivo del intercambio es dar cabida a la ejecución de mas aplicaciones de las que
pueden residir
simultáneamente en la memoria del sistema:
Consiste en trasladar el código y los datos de un proceso completo de memoria al
sistema de
almacenamiento secundario , para cargar otro previamente almacenado, no permite a
un proceso utilizar
mas memoria RAM de la que realmente existe en el sistema. Esta técnica puede ser
ineficiente ya que se
tiene que hacer el intercambio completo del proceso, aunque éste solo vaya a ejecutar
una pequeña porción
del código.
Durante el intercambio un proceso puede ser sacado temporalmente de memoria y
llevado a un lugar
especial del disco y posteriormente vuelto a memoria y continuada su ejecución..
El lugar de almacenamiento temporal suele ser un espacio suficientemente grande
como para acomodar
copias de las imágenes de memoria de todos los usuarios.
Asignación Contigua
La memoria principal normalmente se divide en dos particiones:
Sistema operativo residente, normalmente en la parte baja de memoria con los
vectores de interrupción.
Procesos de usuario en la parte alta.
Asignación de partición simple:
Puede utilizarse un esquema de registro de relocalización y limite para proteger un
proceso de usuario de
otro y de cambios del código y datos del sistema operativo .
El registro de relocalización contiene la dirección contiene la dirección física mas
pequeña; el registro limite
contiene el rango de las direcciones lógicas cada dirección lógica debe ser menor al
registro limite
4.1.1 Organizacion de la Memoria
Archivo a parte en diapositivas…..
4.1.2 Administrador de la Memoria
El Administrador De Memoria se refiere a los distintos métodos y operaciones
que se encargan de obtener la máxima utilidad de la memoria, organizando los
procesos y programas que se ejecutan de manera tal que se aproveche de la
mejor manera posible el espacio disponible.
Para poder lograrlo, la operación principal que realiza es la de trasladar la
información que deberá ser ejecutada por el procesador, a la memoria principal.
Actualmente esta administración se conoce como Memoria Virtual ya que no es
la memoria física del procesador sino una memoria virtual que la representa.
Entre algunas ventajas, esta memoria permite que el sistema cuente con una
memoria más extensa teniendo la misma memoria real, con lo que esta se
puede utilizar de manera más eficiente. Y por supuesto, que los programas que
son utilizados no ocupen lugar innecesario.
Las técnicas que existen para la carga de programas en la memoria son:
partición fija, que es la división de la memoria libre en varias partes (de igual o
distinto tamaño) y la partición dinámica, que son las particiones de la memoria
en tamaños que pueden ser variables, según la cantidad de memoria que
necesita cada proceso.
Entre las principales operaciones que desarrolla la administración de memoria
se encuentran la reubicación, que consiste en trasladar procesos activos dentro
y fuera e la memoria principal para maximizar la utilización del procesador; la
protección, mecanismos que protegen los procesos que se ejecutan de
interferencias de otros procesos; uso compartido de códigos y datos, con lo que
el mecanismo de protección permite que ciertos procesos de un mismo
programa que comparten una tarea tengan memoria en común.
4.1.3 Jerarquía de la Memoria
Se conoce como jerarquía de memoria a la organización piramidal de la
memoria en niveles, que tienen los ordenadores. Su objetivo es conseguir el
rendimiento de una memoria de gran velocidad al coste de una memoria de baja
velocidad, basándose en el principio de cercanía de referencias.
Los puntos básicos relacionados con la memoria pueden resumirse en:
* Cantidad
* Velocidad
* Coste
La cuestión de la cantidad es simple, cuanto más memoria haya disponible, más
podrá utilizarse. La velocidad óptima para la memoria es la velocidad a la que el
procesador puede trabajar, de modo que no haya tiempos de espera entre
cálculo y cálculo, utilizados para traer operandos o guardar resultados. En suma,
el costo de la memoria no debe ser excesivo, para que sea factible construir un
equipo accesible.
Como puede esperse los tres factores compiten entre sí, por lo que hay que
encontrar un equilibrio. Las siguientes afirmaciones son válidas:
* A menor tiempo de acceso mayor coste
* A mayor capacidad menor coste
* A mayor capacidad menor velocidad.
Se busca entonces contar con capacidad suficiente de memoria, con una
velocidad que sirva para satisfacer la demanda de rendimiento y con un coste
que no sea excesivo. Gracias a un principio llamado cercanía de referencias, es
factible utilizar una mezcla de los distintos tipos y lograr un rendimiento cercano
al de la memoria más rápida.
Los niveles que componen la jerarquía de memoria habitualmente son:
* Nivel 0: Registros
* Nivel 1: Memoria caché
* Nivel 2: Memoria principal
* Nivel 3: Disco duro (con el mecanismo de memoria virtual)
Mc.!
4.1.4 Estrategias para Administración de Memoria
De las diversas organizaciones de memoria tratadas en el tema anterior
únicamente las que realizan una asignación no contigua (paginación,
segmentación y segmentación paginada) del almacenamiento permiten
implantar una administración virtual de la memoria. Para cualquiera de las tres
formas de organizar esta memoria virtual habrá que determinar:
Estrategias de obtención. Determinan cuándo se debe transferir una página
o un segmento del almacenamiento secundaria al primario. Las estrategias de
obtención por demanda esperan a que un proceso en ejecución haga referencia
a una página o a un segmento antes de traerla/lo. Los esquemas de obtención
anticipada intentan determinar por adelantado a qué páginas o segmentos hará
referencia un proceso. Si la probabilidad de una referencia es alta y hay espacio
disponible, entonces se trae al almacenamiento primario la página o segmento
antes de que se haga la referencia explícita
Estrategias de colocación. Determinan en qué lugar de la memoria principal
se debe colocar una página o un segmento entrante. Los sistemas de
paginación vuelven trivial la decisión de colocación, porque una página entrante
se puede ubicar en cualquier marco de página disponible. Los sistemas con
segmentación requieren estrategias de colocación como las tratadas en el
contexto de los sistemas de multiprogramación con particiones dinámicas.
Estrategias de reemplazo. Sirven para decidir qué página o segmento se
debe desplazar para dejar espacio a una página o segmento entrante cuando
está completamente ocupada la memoria principal.
4.1.5 Multiprogramación con Particiones Fijas y Variables
!! Multiprogramación con particiones fijas
Para poder implementar la multiprogramación, se puede hacer uso de
particiones fijas o variables en la memoria. En el caso de las particiones fijas, la
memoria se puede organizar dividiéndose en diversas partes, las cuales pueden
variar en tamaño. Esta partición la puede hacer el usuario en forma manual, al
iniciar una sesión con la máquina.
Una vez implementada la partición, hay dos maneras de asignar los procesos a
ella. La primera es mediante el uso de una cola única que asigna los procesos a
los espacios disponibles de la memoria conforme se vayan desocupando. El
tamaño del hueco de memoria disponible es usado para localizar en la cola el
primer proceso que quepa en él. Otra forma de asignación es buscar en la cola
el proceso de tamaño mayor que se ajuste al hueco, sin embargo hay que tomar
en cuenta que tal método discrimina a los procesos más pequeños. Dicho
problema podría tener solución si se asigna una partición pequeña en la
memoria al momento de hacer la partición inicial, el cual sería exclusivo para
procesos pequeños.
Esta idea nos lleva a la implementación de otro método para particiones fijas,
que es el uso de diferentes colas independientes exclusivas para cierto rango en
el tamaño de los procesos. De esta manera al llegar un proceso, éste sería
asignado a la cola de tamaño más pequeño que la pueda aceptar. La desventaja
en esta organización es que si una de las colas tiene una larga lista de procesos
en espera, mientras otra cola esta vacía, el sector de memoria asignado para
ese tamaño de procesos estaría desperdiciándose.
!! Multiprogramación con particiones variables
Este esquema fue originalmente usado por el sistema operativo IBM OS/360
(llamado MFT), el cual ya no está en uso. El sistema operativo lleva una tabla
indicando cuáles partes de la memoria están disponibles y cuáles están
ocupadas. Inicialmente, toda la memoria está disponible para los procesos de
usuario y es considerado como un gran bloque o hueco único de memoria.
Cuando llega un proceso que necesita memoria, buscamos un hueco lo
suficientemente grande para el proceso. Si encontramos uno, se asigna
únicamente el espacio requerido, manteniendo el resto disponible para futuros
procesos que requieran de espacio. Cuando a un proceso se le asigna un
espacio y es cargado a la memoria principal, puede entonces competir para el
uso del CPU.
4.2 Memoria Real
La memoria real o principal es en donde son ejecutados los programas y
procesos de una computadora y es el espacio real que existe en memoria para
que se ejecuten los procesos. Por lo general esta memoria es de mayor costo
que la memoria secundaria, pero el acceso a la información contenida en ella es
de más rápido acceso. Solo la memoria cache es más rápida que la principal,
pero su costo es a su vez mayor.
Administración de la memoria con mapas de bits
Este tipo de administración divide la memoria en unidades de asignación, las
cuales pueden ser tan pequeñas como unas cuantas palabras o tan grandes
como varios kilobytes. A cada unidad de asignación le corresponde un bit en el
mapa de bits, el cual toma el valor de 0 si la unidad está libre y 1 si está ocupada
(o viceversa). La figura 6 muestra una parte de la memoria y su correspondiente
mapa de bits.
Administración de la memoria con listas ligadas
Otra forma de mantener un registro de la memoria es mediante una lista ligada
de los segmentos de memoria asignados o libres, en donde un segmento puede
ser un proceso o un hueco entre dos procesos. La memoria de la figura 7(a) está
mostrada como una lista ligada de segmentos en la figura 7(b). Cada entrada de
la lista especifica un hueco (H) o un proceso (P), la dirección donde comienza,
su longitud y un apuntador a la siguiente entrada.
Asignación del hueco de intercambio
En algunos sistemas, cuando el proceso se encuentra en la memoria, no hay un
hueco en el disco asignado a él. Cuando deba intercambiarse, se deberá asignar
un hueco para él en el área de intercambio del disco. Los algoritmos para la
administración del hueco de intercambio son los mismos que se utilizan para la
administración de la memoria principal.
En otros sistemas, al caerse un proceso, se le asigna un hueco de intercambio
en el disco. Cuando el proceso sea intercambiado, siempre pasará al hueco
asignado, en vez de ir a otro lugar cada vez. Cuando el proceso concluya, se
libera el hueco de intercambio. La única diferencia es que el hueco en disco
necesario para un proceso debe representarse como un número entero de
bloques del disco. Por ejemplo, un proceso de 13.5 K debe utilizar 14K (usando
bloques de 1K).
4.2.1 Administración de Memoria con Mapa de Bits
La memoria se divide en unidades de asignación, a cada asignación le
correspoden un bit en el mapa de bits, un mapa de bits es una forma sencilla
para llevar un registro de las palabras de la memoria en una cantidad fija de
memoria.
4.2.2 Administración de Memoria con Listas Enlazadas
4.2.3 Distribución del Espacio para Intercambio
4.3 Memoria Virtual
4.3.1 Paginación Memoria Virtual
En sistemas operativos de computadoras, los sistemas de paginación de
memoria dividen los programas en pequeñas partes o páginas. Del mismo
modo, la memoria es dividida en trozos del mismo tamaño que las páginas
llamados marcos de página. De esta forma, la cantidad de memoria
desperdiciada por un proceso es el final de su última página, lo que minimiza la
fragmentación interna y evita la externa.
En un momento cualquiera, la memoria se encuentra ocupada con páginas de
diferentes procesos, mientras que algunos marcos están disponibles para su
uso. El sistema operativo mantiene una lista de estos últimos marcos, y una
tabla por cada proceso, donde consta en qué marco se encuentra cada página
del proceso. De esta forma, las páginas de un proceso pueden no estar
contiguamente ubicadas en memoria, y pueden intercalarse con las páginas de
otros procesos.
En la tabla de páginas de un proceso, se encuentra la ubicación del marco que
contiene a cada una de sus páginas. Las direcciones lógicas ahora se forman
como un número de página y de un desplazamiento dentro de esa página. El
número de página es usado como un índice dentro de la tabla de páginas, y una
vez obtenida la dirección real del marco de memoria, se utiliza el desplazamiento
para componer la dirección real. Este proceso es realizado en el hardware del
computador.
De esta forma, cuando un proceso es cargado en memoria, se cargan todas sus
páginas en marcos libres y se completa su tabla de páginas.
Paginación en memoria virtual
El único inconveniente del sistema de paginación pura es que todas las páginas
de un proceso deben estar en memoria para que pueda ejecutar. Esto hace que
si los programas son de tamaño considerable, no puedan cargarse muchos a la
vez, disminuyendo el grado de multiprogramación del sistema. Para evitar esto,
y aprovechando el principio de cercanía de referencias donde se puede esperar
que un programa trabaje con un conjunto cercano de referencias a memoria (es
decir con un conjunto residente más pequeño que el total de sus páginas), se
permitirá que algunas páginas del proceso sean guardadas en un espacio de
intercambio (en memoria secundaria) mientras no se necesiten.
Cuando la paginación se utiliza junto con memoria virtual, el sistema operativo
mantiene además el conocimiento sobre qué páginas están en memoria principal
y cuáles no, usando la tabla de paginación. Si una página buscada está marcada
como no disponible (tal vez porque no está presente en la memoria física, pero
sí en el área de intercambio), cuando la CPU intenta referenciar una dirección de
memoria en esa página, la MMU responde levantando una excepción
(comúnmente llamada fallo de página). Si la página se encuentra en el área de
intercambio, se salta a una rutina que invoca una operación llamada un
intercambio de página, para traer a memoria principal la página requerida. La
operación lleva varios pasos. Primero se selecciona una página en memoria, por
ejemplo una que no haya sido usada recientemente (para más detalles ver
algoritmos de reemplazo de páginas). Si la página fue modificada, se escribe la
misma en el espacio de intercambio. El siguiente paso en el proceso es leer la
información en la página necesitada desde el espacio de intercambio). Cuando
esto sucede, las tablas para traducción de direcciones virtuales a reales son
actualizadas para reflejar los contenidos de la memoria física. Entonces el
intercambio de página sale, y el programa que usó la dirección que causó la
excepción es vuelto a ejecutar desde el punto en que se dio la misma y continúa
como si nada hubiera pasado. También es posible que: una dirección virtual es
marcada como no disponible, porque no fue localizada previamente. En estos
casos, una página de memoria es localizada y llenada con ceros, la tabla de
paginación es modificada para mostrar los cambios y el programa se reinicia
como en el otro caso.
4.3.2 Segmentacion Memoria Virtual
Es un esquema de manejo de memoria mediante el cual la estructura del
programa refleja su división lógica; llevándose a cabo una agrupación lógica de
la información en bloques de tamaño variable denominados segmentos. Cada
uno de ellos tienen información lógica del programa: subrutina, arreglo, etc.
Luego, cada espacio de direcciones de programa consiste de una colección de
segmentos, que generalmente reflejan la división lógica del programa. La
segmentación permite alcanzar los siguientes objetivos:
1. Modularidad de programas: cada rutina del programa puede ser un bloque
sujeto a cambios y recopilaciones, sin afectar por ello al resto del programa.
2. Estructuras de datos de largo variable: ejm. Stack, donde cada estructura
tiene su propio tamaño y este puede variar.
3. Protección: se puede proteger los módulos del segmento contra accesos no
autorizados.
4. Comparición: dos o más procesos pueden ser un mismo segmento, bajo
reglas de protección; aunque no sean propietarios de los mismos.
5. Enlace dinámico entre segmentos: puede evitarse realizar todo el proceso
de enlace antes de comenzar a ejecutar un programa. Los enlaces se
establecerán solo cuando sea necesario.
Ventajas de la segmentación El esquema de segmentación ofrece las siguientes
ventajas:
* El programador puede conocer las unidades lógicas de su programa,
dándoles un tratamiento particular.
* Es posible compilar módulos separados como segmentos el enlace entre los
segmentos puede suponer hasta tanto se haga una referencia entre segmentos.
* Debido a que es posible separar los módulos se hace más fácil la
modificación de los mismos. Cambios dentro de un modulo no afecta al resto de
los módulos.
* Es fácil el compartir segmentos.
* Es posible que los segmentos crezcan dinámicamente según las
necesidades del programa en ejecución.
* Existe la posibilidad de definir segmentos que aun no existan. Así, no se
asignara memoria, sino a partir del momento que sea necesario hacer usos del
segmento. Un ejemplo de esto, serian los arreglos cuya dimensión no se conoce
hasta tanto no se comienza a ejecutar el programa. En algunos casos, incluso
podría retardar la asignación de memoria hasta el momento en el cual se
referencia el arreglo u otra estructura de dato por primera vez.
Desventajas de la segmentación
* Hay un incremento en los costos de hardware y de software para llevar a
cabo la implantación, así como un mayor consumo de recursos: memoria,
tiempo de CPU, etc.
* Debido a que los segmentos tienen un tamaño variable se pueden presentar
problemas de fragmentación externas, lo que puede ameritar un plan de
reubicación de segmentos en memoria principal.
* Se complica el manejo de memoria virtual, ya que los discos almacenan la
información en bloques de tamaños fijos, mientras los segmentos son de tamaño
variable. Esto hace necesaria la existencia de mecanismos más costosos que
los existentes para paginación.
* Al permitir que los segmentos varíen de tamaño, puede ser necesarios
planes de reubicación a nivel de los discos, si los segmentos son devueltos a
dicho dispositivo; lo que conlleva a nuevos costos.
* No se puede garantizar, que al salir un segmento de la memoria, este pueda
ser traído fácilmente de nuevo, ya que será necesario encontrar nuevamente un
área de memoria libre ajustada a su tamaño.
* La comparticion de segmentos permite ahorrar memoria, pero requiere de
mecanismos adicionales da hardware y software.
4.3.3 Algoritmos de Sustitucion de Paginas
4.3.4 Aspectos de Diseño para el Sistema
4.3.5 Liberacion de Paginas
Unidad 5 Administracion de Dispositivos de E/S
5.1 Principios de Hardware de I O
Funciones del Sistema de Archivos
Los usuarios deben poder crear, modificar y borrar archivos.
Se deben poder compartir los archivos de una manera cuidadosamente
controlada [7, Deitel].
El mecanismo encargado de compartir los archivos debe proporcionar varios
tipos de acceso controlado:
Ej.: “Acceso de Lectura”, “Acceso de Escritura”, “Acceso de Ejecución”, varias
combinaciones de estos, etc. Se debe poder estructurar los archivos de la
manera más apropiada a cada aplicación. Los usuarios deben poder ordenar la
transferencia de información entre archivos.
Se deben proporcionar posibilidades de “respaldo” y “recuperación” para
prevenirse contra:
La pérdida accidental de información. La destrucción maliciosa de información.
Se debe poder referenciar a los archivos mediante “Nombres Simbólicos”,
brindando “Independencia de Dispositivos”. En ambientes sensibles, el sistema
de archivos debe proporcionar posibilidades de “Cifrado” y “Descifrado”.
El sistema de archivos debe brindar una interfase favorable al usuario:
Debe suministrar una “visión lógica” de los datos y de las funciones que serán
ejecutadas, en vez de una “visión física”. El usuario no debe tener que
preocuparse por: Los dispositivos particulares. Dónde serán almacenados los
datos. El formato de los datos en los dispositivos. Los medios físicos de la
transferencia de datos hacia y desde los dispositivos.
Inicio: Fin: El Sistema de Archivos
Un “Archivo” es un conjunto de registros relacionados [23, Tanenbaum].
El “Sistema de Archivos” es un componente importante de un S. O. y suele
contener [7, Deitel]:
“Métodos de acceso” relacionados con la manera de acceder a los datos
almacenados en archivos. “Administración de archivos” referida a la provisión de
mecanismos para que los archivos sean almacenados, referenciados,
compartidos y asegurados. “Administración del almacenamiento auxiliar” para la
asignación de espacio a los archivos en los dispositivos de almacenamiento
secundario. “Integridad del archivo” para garantizar la integridad de la
información del archivo. El sistema de archivos está relacionado especialmente
con la administración del espacio de almacenamiento secundario,
fundamentalmente con el almacenamiento de disco. Una forma de organización
de un sistema de archivos puede ser la siguiente:
Se utiliza una “raíz ” para indicar en qué parte del disco comienza el “directorio
raíz ”. El “directorio raíz ” apunta a los “directorios de usuarios”. Un “directorio de
usuario” contiene una entrada para cada uno de los archivos del usuario. Cada
entrada de archivo apunta al lugar del disco donde está almacenado el archivo
referenciado. Los nombres de archivos solo necesitan ser únicos dentro de un
directorio de usuario dado. El nombre del sistema para un archivo dado debe ser
único para el sistema de archivos.
En sistemas de archivo “jerárquicos” el nombre del sistema para un archivo
suele estar formado como el “nombre de la trayectoria” del directorio raíz al
archivo.
Inicio: Fin:
Archivos
Se considerará el punto de vista del usuario.
Nombre de los Archivos
Las reglas exactas para los nombres de archivos varían de sistema a sistema
[23, Tanenbaum].
Algunos sistemas de archivos distinguen entre las letras mayúsculas y
minúsculas, mientras que otros no.
Muchos S. O. utilizan nombres de archivo con dos partes, separadas por un
punto:
La parte posterior al punto es la extensión de archivo y generalmente indica algo
relativo al archivo, aunque las extensiones suelen ser meras convenciones.
Inicio: Fin: Estructura de un Archivo
Los archivos se pueden estructurar de varias maneras, las más comunes son
[23, Tanenbaum]:
“Secuencia de bytes”: El archivo es una serie no estructurada de bytes. Posee
máxima flexibilidad. El S. O. no ayuda pero tampoco estorba. “Secuencia de
registros”: El archivo es una secuencia de registros de longitud fija, cada uno con
su propia estructura interna. “Árbol ”: El archivo consta de un árbol de registros,
no necesariamente de la misma longitud. Cada registro tiene un campo key
(llave o clave) en una posición fija del registro. El árbol se ordena mediante el
campo de clave para permitir una rápida búsqueda de una clave particular.
Inicio: Fin: Tipos de Archivos
Muchos S. O. soportan varios tipos de archivos, por ej.: archivos regulares,
directorios, archivos especiales de caracteres, archivos especiales de bloques,
etc., donde [23, Tanenbaum]:
Los Archivos Regulares son aquellos que contienen información del usuario. Los
Directorios son archivos de sistema para el mantenimiento de una estructura del
sistema de archivos. Los Archivos Especiales de Caracteres: Tienen relación
con la e / s. Se utilizan para modelar dispositivos seriales de e / s (terminales,
impresoras, redes, etc.). Los Archivos Especiales de Bloques se utilizan para
modelar discos. Inicio: Fin: Acceso a un Archivo
Los tipos de acceso más conocidos son:
Acceso Secuencial: el proceso lee en orden todos los registros del archivo
comenzando por el principio, sin poder: Saltar registros. Leer en otro orden.
Acceso Aleatorio: el proceso puede leer los registros en cualquier orden
utilizando dos métodos para determinar el punto de inicio de la lectura: Cada
operación de lectura (read) da la posición en el archivo con la cual iniciar. Una
operación especial (seek) establece la posición de trabajo pudiendo luego leerse
el archivo secuencialmente. Inicio: Fin: Atributos de Archivo
Cada archivo tiene:
Su nombre y datos. Elementos adicionales llamados atributos, que varían
considerablemente de sistema a sistema. Algunos de los posibles atributos de
archivo son [23, Tanenbaum]: “Protección”: quién debe tener acceso y de qué
forma. “Contraseña”: contraseña necesaria para acceder al archivo. “Creador”:
identificador de la persona que creó el archivo. “Propietario”: propietario actual.
“Bandera exclusivo - para - lectura”: 0 lectura / escritura, 1 para lectura
exclusivamente. “Bandera de ocultamiento”: 0 normal, 1 para no exhibirse en
listas. “Bandera de sistema”: 0 archivo normal, 1 archivo de sistema. “Bandera
de biblioteca”: 0 ya se ha respaldado, 1 necesita respaldo. “Bandera ascii /
binario”: 0 archivo en ascii, 1 archivo en binario. “Bandera de acceso aleatorio”: 0
solo acceso secuencial, 1 acceso aleatorio. “Bandera temporal”: 0 normal, 1
eliminar al salir del proceso. “Banderas de cerradura”: 0 no bloqueado, distinto
de 0 bloqueado. “Longitud del registro”: número de bytes en un registro.
“Posición de la llave”: ajuste de la llave dentro de cada registro. “Longitud de la
llave”: número de bytes en el campo llave. “Tiempo de creación”: fecha y hora de
creación del archivo. “Tiempo del último acceso”: fecha y hora del último acceso
al archivo. “Tiempo de la última modificación”: fecha y hora de la última
modificación al archivo. “Tamaño actual”: número de bytes en el archivo.
“Tamaño máximo”: tamaño máximo al que puede crecer el archivo. Inicio: Fin:
Operaciones con Archivos
Las llamadas más comunes al sistema relacionadas con los archivos son [23,
Tanenbaum]:
Create (crear): el archivo se crea sin datos. Delete (eliminar): si el archivo ya no
es necesario debe eliminarse para liberar espacio en disco. Ciertos S. O.
eliminan automáticamente un archivo no utilizado durante “n” días. Open (abrir):
antes de utilizar un archivo, un proceso debe abrirlo. La finalidad es permitir que
el sistema traslade los atributos y la lista de direcciones en disco a la memoria
principal para un rápido acceso en llamadas posteriores. Close (cerrar): cuando
concluyen los accesos, los atributos y direcciones del disco ya no son
necesarios, por lo que el archivo debe cerrarse y liberar la tabla de espacio
interno. Read (leer): los datos se leen del archivo; quien hace la llamada debe
especificar la cantidad de datos necesarios y proporcionar un buffer para
colocarlos. Write (escribir): los datos se escriben en el archivo, en la posición
actual. El tamaño del archivo puede aumentar (agregado de registros) o no
(actualización de registros). Append (añadir): es una forma restringida de “write”.
Solo puede añadir datos al final del archivo. Seek (buscar): especifica el punto
donde posicionarse. Cambia la posición del apuntador a la posición activa en
cierto lugar del archivo. Get attributes (obtener atributos): permite a los procesos
obtener los atributos del archivo. Set attributes (establecer atributos): algunos
atributos pueden ser determinados por el usuario y modificados luego de la
creación del archivo. La información relativa al modo de protección y la mayoría
de las banderas son un ejemplo obvio. Rename (cambiar de nombre): permite
modificar el nombre de un archivo ya existente. Inicio: Fin: Archivos Mapeados a
Memoria
Algunos S. O. permiten asociar los archivos con un espacio de direcciones de un
proceso en ejecución [23, Tanenbaum].
Se utilizan las llamadas al sistema “map” y “unmap”:
“Map”: utiliza un nombre de archivo y una dirección virtual y hace que el S. O.
asocie al archivo con la dirección virtual en el espacio de direcciones, por lo cual
las lecturas o escrituras de las áreas de memoria asociadas al archivo se
efectúan también sobre el archivo mapeado. “Unmap”: elimina los archivos del
espacio de direcciones y concluye la operación de asociación. El mapeo de
archivos elimina la necesidad de programar la e / s directamente, facilitando la
programación. Los principales problemas relacionados son:
Imposibilidad de conocer a priori la longitud del archivo de salida, el que podría
superar a la memoria. Dificultad para compartir los archivos mapeados evitando
inconsistencias, ya que las modificaciones hechas en las páginas no se verán
reflejadas en el disco hasta que dichas páginas sean eliminadas de la memoria.
Inicio: Fin: Directorios
Generalmente son utilizados por los S. O. para llevar un registro de los archivos
[23, Tanenbaum].
En muchos sistemas son a su vez también archivos.
Sistemas Jerárquicos de Directorios
El directorio contiene un conjunto de datos por cada archivo referenciado.
Una posibilidad es que el directorio contenga por cada archivo referenciado [7,
Deitel]:
El nombre. Sus atributos. Las direcciones en disco donde se almacenan los
datos. Otra posibilidad es que cada entrada del directorio contenga: El nombre
del archivo. Un apuntador a otra estructura de datos donde se encuentran los
atributos y las direcciones en disco. Al abrir un archivo el S. O.: Busca en su
directorio el nombre del archivo. Extrae los atributos y direcciones en disco.
Graba esta información en una tabla de memoria real. Todas las referencias
subsecuentes al archivo utilizarán la información de la memoria principal. El
número y organización de directorios varía de sistema en sistema: Directorio
único: el sistema tiene un solo directorio con todos los archivos de todos los
usuarios (ver Figura 4.1 [23, Tanenbaum]). Un directorio por usuario: el sistema
habilita un solo directorio por cada usuario (ver Figura 4.2 [23, Tanenbaum]). Un
árbol de directorios por usuario: el sistema permite que cada usuario tenga
tantos directorios como necesite, respetando una jerarquía general (ver Figura
4.3 [23, Tanenbaum]).
Inicio: Fin:
Nombre de las Rutas de Acceso
Cuando el sistema de archivos está organizado como un árbol de directorios se
necesita una forma de determinar los nombres de los archivos.
Los principales métodos para nombres de los archivos son [23, Tanenbaum]:
Ruta de Acceso Absoluta: Cada archivo tiene una ruta de acceso absoluta.
Consta de la ruta de acceso desde el directorio raíz hasta el archivo. Los
componentes de la ruta de acceso se separan mediante algún carácter llamado
“separador”. Ruta de Acceso Relativa: Se utiliza junto con el concepto de
directorio de trabajo o directorio activo. Todos los nombres que no comiencen en
el directorio raíz se toman en relación con el directorio de trabajo. El nombre
absoluto de la ruta de acceso siempre funciona, sin importar cual sea el
directorio de trabajo. Inicio: Fin: Operaciones con Directorios
Las llamadas al sistema permitidas para el manejo de los directorios tienen
variación de sistema a sistema [23, Tanenbaum].
Las más comunes son las siguientes:
Create (crear): se crea un directorio vacío. Delete (eliminar): se elimina un
directorio, que debe estar vacío. Opendir (abrir directorio): se pueden leer los
directorios: Antes de poder leer un directorio, éste debe ser abierto. Closedir
(cerrar directorio): cuando se ha leído un directorio, éste debe ser cerrado para
liberar el espacio correspondiente de la tabla interna. Readdir (leer directorio):
regresa la siguiente entrada en un directorio abierto, sin importar el tipo de
estructura de directorios que se utilice. Rename (cambiar de nombre): cambia el
nombre de un directorio de manera similar al cambio para archivos. Link (ligar):
es una técnica que permite que un archivo aparezca en más de un directorio:
Especifica un archivo existente y el nombre de una ruta de acceso. Crea un
enlace del archivo ya existente con el nombre especificado en la ruta de acceso.
Unlink (desligar): se elimina una entrada del directorio: Si el archivo que se
desea desligar aparece solo en un directorio (el caso normal): Se elimina del
sistema de archivos. Si el archivo que se desea desligar, está presente en varios
directorios: Solo se elimina la ruta de acceso especificada. Las demás rutas
permanecen. Inicio: Fin: Implantación del Sistema de Archivos y sus Relaciones
con la Asignación y Liberación de Espacio
Se consideran aspectos tales como [7, Deitel]:
La forma de almacenamiento de archivos y directorios. La administración del
espacio en disco. La forma de hacerlo de manera eficiente y confiable. Se deben
tener presentes problemas tales como la “fragmentación” creciente del espacio
en disco: Ocasiona problemas de performance al hacer que los archivos se
desperdiguen a través de bloques muy dispersos. Una técnica para aliviar el
problema de la “fragmentación” consiste en realizar periódicamente:
“Condensación”: se pueden “reorganizar” los archivos expresamente o
automáticamente según algún criterio predefinido. “Recolección de basura o
residuos”: se puede hacer fuera de línea o en línea, con el sistema activo, según
la implementación. Inicio: Fin: Implantación de Archivos
El aspecto clave de la implantación del almacenamiento de archivos es el
registro de los bloques asociados a cada archivo [7, Deitel].
Algunos de los métodos utilizados son los siguientes:
Asignación contigua o adyacente: Los archivos son asignados a áreas contiguas
de almacenamiento secundario. Las principales ventajas son: Facilidad de
implantación, ya que solo se precisa el número del bloque de inicio para localizar
un archivo. Rendimiento excelente respecto de la e / s. Los principales defectos
son: Se debe conocer el tamaño máximo del archivo al crearlo. Produce una
gran fragmentación de los discos. Asignación no contigua: Son esquemas de
almacenamiento más dinámicos, destacándose los siguientes: Asignación
encadenada orientada hacia el sector: El disco se considera compuesto de
sectores individuales. Los archivos constan de varios sectores que pueden estar
dispersos por todo el disco. Los sectores que pertenecen a un archivo común
contienen apuntadores de uno a otro formando una “lista encadenada”. Una
“lista de espacio libre” contiene entradas para todos los sectores libres del disco.
Las ampliaciones o reducciones en el tamaño de los archivos se resuelven
actualizando la “lista de espacio libre” y no hay necesidad de condensación. Las
principales desventajas son: Debido a la posible dispersión en el disco, la
recuperación de registros lógicamente contiguos puede significar largas
búsquedas. El mantenimiento de la estructura de “listas encadenadas” significa
una sobrecarga en tiempo de ejecución. Los apuntadores de la estructura de
lista consumen espacio en disco. Asignación por bloques: Es más eficiente y
reduce la sobrecarga en ejecución. Es una mezcla de los métodos de asignación
contigua y no contigua. Se asignan bloques de sectores contiguos en vez de
sectores individuales. El sistema trata de asignar nuevos bloques a un archivo
eligiendo bloques libres lo más próximos posible a los bloques del archivo
existentes. Las formas más comunes de implementar la asignación por bloques
son: Encadenamiento de bloques. Encadenamiento de bloques de índice.
Transformación de archivos orientada hacia bloques. Encadenamiento de
bloques o lista ligada: Las entradas en el directorio de usuarios apuntan al
primer bloque de cada archivo. Cada uno de los bloques de longitud fija que
forman un archivo contiene dos partes: Un bloque de datos. Un apuntador al
bloque siguiente. Cada bloque contiene varios sectores. Frecuentemente el
tamaño de un bloque se corresponde con el de una pista completa del disco.
Localizar un registro determinado requiere: Buscar en la cadena de bloques
hasta encontrar el bloque apropiado. Buscar en el bloque hasta encontrar el
registro. El examen de la cadena desde el principio puede ser lento ya que debe
realizarse de bloque en bloque, y pueden estar dispersos por todo el disco. La
inserción y el retiro son inmediatos, dado que se deben modificar los
apuntadores del bloque precedente. Se pueden usar “listas de encadenamiento
doble”, hacia adelante y hacia atrás, con lo que se facilita la búsqueda (ver
Figura 4.4 [23, Tanenbaum]).
Encadenamiento de bloques de índices: Los apuntadores son colocados en
varios bloques de índices separados: Cada bloque de índices contiene un
número fijo de elementos. Cada entrada contiene un identificador de registros y
un apuntador a ese registro. Si es necesario utilizar más de un bloque de índices
para describir un archivo, se encadena una serie de bloques de índices. La gran
ventaja es que la búsqueda puede realizarse en los propios bloques de índices.
Los bloques de índices pueden mantenerse juntos en el almacenamiento
secundario para acortar la búsqueda, pero para mejor performance podrían
mantenerse en el almacenamiento primario. La principal desventaja es que las
inserciones pueden requerir la reconstrucción completa de los bloques de
índices: Una posibilidad es dejar vacía una parte de los bloques de índices para
facilitar inserciones futuras y retardar las reconstrucciones. Es suficiente que el
dato del directorio contenga el número de bloque inicial para localizar todos los
bloques restantes, sin importar el tamaño del archivo (ver Figura 4.5 [7, Deitel]).
Transformación de archivos orientada hacia bloques: Se utilizan números de
bloques en vez de apuntadores. Los números de bloques se convierten
fácilmente a direcciones de bloques gracias a la geometría del disco. Se
conserva un mapa del archivo, conteniendo una entrada para cada bloque del
disco. Las entradas en el directorio del usuario apuntan a la primera entrada al
mapa del archivo para cada archivo. Cada entrada al mapa del archivo contiene
el número del bloque siguiente de ese archivo. La entrada al mapa del archivo
correspondiente a la última entrada de un archivo determinado se ajusta a algún
valor “centinela” (“nil”) para indicar que se alcanzó el último bloque de un
archivo. El sistema puede mantener una lista de bloques libres. La principal
ventaja es que las cercanías físicas del disco se reflejan en el mapa del archivo
(ver Figura 4.6 [7, Deitel]).
Nodos-i (nodos índices): Se asocia a cada archivo una pequeña tabla, llamada
nodo-i (nodo índice): Contiene los atributos y direcciones en disco de los bloques
del archivo. Se traslada del disco a la memoria principal al abrir el archivo. En
rigor, almacena solo las primeras direcciones en disco: o Si el archivo es
pequeño, toda la información está en el nodo-i. o Si el archivo es grande, una de
las direcciones en el nodo-i es la dirección de un bloque en el disco llamado
bloque simplemente indirecto: Contiene las direcciones en disco adicionales. Si
resulta insuficiente, otra dirección en el nodo-i, el bloque doblemente indirecto,
contiene la dirección de un bloque que presenta una lista de los bloques
simplemente indirectos: Cada bloque simplemente indirecto apunta a un grupo
de bloques de datos. De ser necesario se pueden utilizar bloques triplemente
indirectos (ver Figura 4.7 [23, Tanenbaum]).
Inicio: Fin:
Implantación de Directorios
Para abrir un archivo el S. O. utiliza información del directorio:
El directorio contiene la información necesaria para encontrar los bloques en el
disco. El tipo de información varía según el sistema. La principal función del
sistema de directorios es asociar el nombre del archivo con la información
necesaria para localizar los datos. Un aspecto íntimamente ligado con esto es la
posición de almacenamiento de los atributos:
Una posibilidad es almacenarlos en forma directa dentro del dato del directorio.
Otra posibilidad es almacenar los atributos en el nodo-i en vez de utilizar la
entrada del directorio. Inicio: Fin: Archivos Compartidos
Frecuentemente conviene que los archivos compartidos
simultáneamente en distintos directorios de distintos usuarios.
aparezcan
El propio sistema de archivos es una gráfica dirigida acíclica en vez de un árbol
[23, Tanenbaum].
La conexión entre un directorio y un archivo de otro directorio al cual comparten
se denomina enlace.
Si los directorios realmente contienen direcciones en disco:
Se debe tener una copia de las direcciones en disco en el directorio que accede
al archivo compartido al enlazar el archivo. Se debe evitar que los cambios
hechos por un usuario a través de un directorio no sean visibles por los demás
usuarios, para lo que se consideraran dos soluciones posibles. Primer solución:
Los bloques del disco no se enlistan en los directorios, sino en una pequeña
estructura de datos asociada al propio archivo. Los directorios apuntarían solo a
esa pequeña estructura de datos, que podría ser el nodo-i. Segunda solución: El
enlace se produce haciendo que el sistema cree un nuevo archivo de tipo “link”.
El archivo “link”: Ingresa al directorio del usuario que accede a un archivo de otro
directorio y usuario. Solo contiene el nombre de la ruta de acceso del archivo al
cual se enlaza. Este criterio se denomina enlace simbólico. Desventajas de la
primer solución: La creación de un enlace: No modifica la propiedad respecto de
un archivo. Aumenta el contador de enlaces del nodo-i: El sistema sabe el
número de entradas de directorio que apuntan en cierto momento al archivo. Si
el propietario inicial del archivo intenta eliminarlo, surge un problema para el
sistema: Si elimina el archivo y limpia el nodo-i, el directorio que enlazo al
archivo tendrá una entrada que apunta a un nodo-i no válido. Si el nodo-i se
reasigna a otro archivo el enlace apuntará al archivo incorrecto. El sistema:
Puede ver por medio del contador de enlaces en el nodo-i que el archivo sigue
utilizándose. No puede localizar todas las entradas de directorio asociadas a ese
archivo para eliminarlas. La solución podría ser: Eliminar la entrada del directorio
inicialmente propietario del archivo. Dejar intacto el nodo-i: Se daría el caso que
el directorio que posee el enlace es el único que posee una entrada de directorio
para un archivo de otro directorio, para el cual dicho archivo ya no existe. Esto
no ocurre con los enlaces simbólicos ya que solo el propietario verdadero tiene
un apuntador al nodo-i: Los usuarios enlazados al archivo solo tienen nombres
de rutas de acceso y no apuntadores a nodo-i. Cuando el propietario elimina un
archivo, este se destruye. Desventajas de la segunda solución: El principal
problema es su costo excesivo, especialmente en accesos a disco, puesto que
se debe leer el archivo que contiene la ruta de acceso, analizarla y seguirla
componente a componente hasta alcanzar el nodo-i. Se precisa un nodo-i
adicional por cada enlace simbólico y un bloque adicional en disco para
almacenar la ruta de acceso. Los archivos pueden tener dos o más rutas de
acceso, debido a lo cual, en búsquedas genéricas se podría encontrar el mismo
archivo por distintas rutas y tratárselo como si fueran archivos distintos. Los
enlaces simbólicos tienen la ventaja de que se pueden utilizar para enlazar
archivos en otras máquinas, en cualquier parte del mundo; se debe proporcionar
solo la dirección de la red de la máquina donde reside el archivo y su ruta de
acceso en esa máquina. Inicio: Fin:
Administración del Espacio en Disco
Existen dos estrategias generales para almacenar un archivo de “n” bytes [23,
Tanenbaum]:
Asignar “n” bytes consecutivos de espacio en el disco:
Tiene el problema de que si un archivo crece será muy probable que deba
desplazarse en el disco, lo que puede afectar seriamente al rendimiento. Dividir
el archivo en cierto número de bloques (no necesariamente) adyacentes:
Generalmente los sistemas de archivos utilizan esta estrategia con bloques de
tamaño fijo. Tamaño del bloque: Dada la forma en que están organizados los
bloques, el sector, la pista y el cilindro son los candidatos obvios como unidades
de asignación.
Si se tiene una unidad de asignación grande, como un cilindro, esto significa que
cada archivo, inclusive uno pequeño, ocupará todo un cilindro; con esto se
desperdicia espacio de almacenamiento en disco.
Si se utiliza una unidad de asignación pequeña, como un sector, implica que
cada archivo constará de muchos bloques; con esto su lectura generará muchas
operaciones de e / s afectando la performance.
Lo anterior indica que la eficiencia en tiempo y espacio tienen un conflicto
inherente.
Generalmente se utilizan como solución de compromiso bloques de 1/2 k, 1k, 2k
o 4k. (ver Figura 4.8 [23, Tanenbaum]).
Hay que recordar que el tiempo de lectura de un bloque de disco es la suma de
los tiempos de:
Búsqueda. Demora rotacional. Transferencia. Registro de los bloques libres: Se
utilizan por lo general dos métodos:
La lista de bloques libres como lista ligada. Un mapa de bits. Lista ligada de
bloques de disco: Cada bloque contiene tantos números de bloques libres como
pueda. Los bloques libres se utilizan para contener a la lista de bloques libres.
Mapa de bits: Un disco con “n” bloques necesita un mapa de bits con “n” bits.
Los bloques libres se representa con “1” y los asignados con “0” (o viceversa).
Generalmente este método es preferible cuando existe espacio suficiente en la
memoria principal para contener completo el mapa de bits. Disk quotas: Para
evitar que los usuarios se apropien de un espacio excesivo en disco, los S. O.
multiusuario proporcionan generalmente un mecanismo para establecer las
cuotas en el disco.
La idea es que:
Un administrador del sistema asigne a cada usuario una proporción máxima de
archivos y bloques. El S. O. garantice que los usuarios no excedan sus cuotas.
Un mecanismo utilizado es el siguiente: Cuando un usuario abre un archivo: Se
localizan los atributos y direcciones en disco. Se colocan en una tabla de
archivos abiertos en la memoria principal. Uno de los atributos indica el
propietario del archivo; cualquier aumento del tamaño del archivo se carga a la
cuota del propietario. Una segunda tabla contiene el registro de las cuotas para
cada uno de los usuarios que tengan un archivo abierto en ese momento, aún
cuando el archivo lo haya abierto otro usuario. Cuando se escribe una nueva
entrada en la tabla de archivos abiertos: Se introduce un apuntador al registro de
la cuota del propietario para localizar los límites. Cuando se añade un bloque a
un archivo: Se incrementa el total de bloques cargados al propietario. Se verifica
este valor contra los límites estricto y flexible (el primero no se puede superar, el
segundo sí). También se verifica el número de archivos.
Inicio: Fin:
Confiabilidad del Sistema de Archivos
Es necesario proteger la información alojada en el sistema de archivos,
efectuando los resguardos correspondientes [23, Tanenbaum].
De esta manera se evitan las consecuencias generalmente catastróficas de la
pérdida de los sistemas de archivos.
Las pérdidas se pueden deber a problemas de hardware, software, hechos
externos, etc.
Manejo de un bloque defectuoso:
Se utilizan soluciones por hardware y por software.
La solución en hardware:
Consiste en dedicar un sector del disco a la lista de bloques defectuosos. Al
inicializar el controlador por primera vez: Lee la “lista de bloques defectuosos”.
Elige un bloque (o pista) de reserva para reemplazar los defectuosos. Registra la
asociación en la lista de bloques defectuosos. En lo sucesivo, las solicitudes del
bloque defectuoso utilizarán el de repuesto. La solución en software: Requiere
que el usuario o el sistema de archivos construyan un archivo con todos los
bloques defectuosos. Se los elimina de la “lista de bloques libres”. Se crea un
“archivo de bloques defectuosos”: Esta constituido por los bloques defectuosos.
No debe ser leído ni escrito. No se debe intentar obtener copias de respaldo de
este archivo. Respaldos (copias de seguridad o de back-up): Es muy importante
respaldar los archivos con frecuencia.
Los respaldos pueden consistir en efectuar copias completas del contenido de
los discos (flexibles o rígidos).
Una estrategia de respaldo consiste en dividir los discos en áreas de datos y
áreas de respaldo, utilizándolas de a pares:
Se desperdicia la mitad del almacenamiento de datos en disco para respaldo.
Cada noche (o en el momento que se establezca), la parte de datos de la unidad
0 se copia a la parte de respaldo de la unidad 1 y viceversa. Otra estrategia es el
vaciado por incrementos o respaldo incremental : Se obtiene una copia de
respaldo periódicamente (por ej.: una vez por mes o por semana), llamada copia
total. Se obtiene una copia diaria solo de aquellos archivos modificados desde la
última copia total; en estrategias mejoradas, se copian solo aquellos archivos
modificados desde la última vez que dichos archivos fueron copiados. Se debe
mantener en el disco información de control como una “lista de los tiempos de
copiado” de cada archivo, la que debe ser actualizada cada vez que se obtienen
copias de los archivos y cada vez que los archivos son modificados. Puede
requerir una gran cantidad de cintas de respaldo dedicadas a los respaldos
diarios entre respaldos completos. Consistencia del sistema de archivos:
Muchos sistemas de archivos leen bloques, los modifican y escriben en ellos
después.
Si el sistema falla antes de escribir en los bloques modificados, el sistema de
archivos puede quedar en un “estado inconsistente”.
La inconsistencia es particularmente crítica si alguno de los bloques afectados
son:
Bloques de nodos-i. Bloques de directorios. Bloques de la lista de bloques libres.
La mayoría de los sistemas dispone de un programa utilitario que verifica la
consistencia del sistema de archivos: Se pueden ejecutar al arrancar el sistema
o a pedido. Pueden actuar sobre todos o algunos de los discos. Pueden efectuar
verificaciones a nivel de bloques y a nivel de archivos. La consistencia del
sistema de archivos no asegura la consistencia interna de cada archivo,
respecto de su contenido. Generalmente pueden verificar también el sistema de
directorios y / o de bibliotecas. Generalmente los utilitarios utilizan dos tablas:
Tabla de bloques en uso. Tabla de bloques libres. Cada bloque debe estar
referenciado en una de ellas. Si un bloque no aparece en ninguna de las tablas
se trata de una falla llamada bloque faltante: No produce daños pero desperdicia
espacio en disco. Se soluciona añadiendo el bloque a la tabla de bloques libres.
También podría detectarse la situación de falla debida a un bloque referenciado
dos veces en la tabla de bloques libres: Esta falla no se produce en los sistemas
de archivos basados en mapas de bits, sí en los basados en tablas o listas. La
solución consiste en depurar la tabla de bloques libres. Una falla muy grave es
que el mismo bloque de datos aparezca referenciado dos o más veces en la
tabla de bloques en uso: Como parte del mismo o de distintos archivos. Si uno
de los archivos se borra, el bloque aparecería en la tabla de bloques libres y
también en la de bloques en uso. Una solución es que el verificador del sistema
de archivos: Asigne un bloque libre. Copie en el bloque libre el contenido del
bloque conflictivo. Actualice las tablas afectando el bloque copia a alguno de los
archivos. Agregue el bloque conflictivo a la tabla de bloques libres. Informe al
usuario para que verifique el daño detectado y la solución dada. Otro error
posible es que un bloque esté en la tabla de bloques en uso y en la tabla de
bloques libres: Se soluciona eliminándolo de la tabla de bloques libres. Las
verificaciones de directorios incluyen controles como: Número de directorios que
apuntan a un nodo-i con los contadores de enlaces almacenados en los propios
nodos-i; en un sistema consistente de archivos deben coincidir. Una posible falla
es que el contador de enlaces sea mayor que el número de entradas del
directorio: Aunque se eliminaran todos los archivos de los directorios el contador
sería distinto de cero y no se podría eliminar el nodo-i. No se trata de un error
serio pero produce desperdicio de espacio en disco con archivos que no se
encuentran en ningún directorio. Se soluciona haciendo que el contador de
enlaces en el nodo-i tome el valor correcto; si el valor correcto es 0, el archivo
debe eliminarse. Otro tipo de error es potencialmente catastrófico: Si dos
entradas de un directorio se enlazan a un archivo, pero el nodo-i indica que solo
existe un enlace, entonces, al eliminar cualquiera de estas entradas de
directorio, el contador del nodo-i tomará el valor 0. Debido al valor 0 el sistema
de archivos lo señala como no utilizado y libera todos sus bloques. Uno de los
directorios apunta hacia un nodo-i no utilizado, cuyos bloques se podrían asignar
entonces a otros archivos. La solución es forzar que el contador de enlaces del
nodo-i sea igual al número de entradas del directorio. También se pueden hacer
verificaciones heurísticas, por ej.: Cada nodo-i tiene un modo, pero algunos
modos son válidos aunque extraños: Ej.: Se prohibe el acceso al propietario y
todo su grupo, pero se permite a los extraños leer, escribir y ejecutar el archivo.
La verificación debería detectar e informar de estas situaciones. Se debería
informar como sospechosos aquellos directorios con excesivas entradas, por ej.,
más de mil. Inicio: Fin: Desempeño del Sistema de Archivos
El acceso al disco es mucho más lento que el acceso a la memoria:
Los tiempos se miden en milisegundos y en nanosegundos respectivamente. Se
debe reducir el número de accesos a disco. La técnica más común para reducir
los accesos a disco es el bloque caché o buffer caché[23, Tanenbaum]: Se
utiliza el término ocultamiento para esta técnica (del francés “cacher”: ocultar).
Un caché es una colección de bloques que pertenecen desde el punto de vista
lógico al disco, pero que se mantienen en memoria por razones de rendimiento.
Uno de los algoritmos más comunes para la administración del caché es el
siguiente: Verificar todas las solicitudes de lectura para saber si el bloque
solicitado se encuentra en el caché. En caso afirmativo, se satisface la solicitud
sin un acceso a disco. En caso negativo, se lee para que ingrese al caché y
luego se copia al lugar donde se necesite. Cuando hay que cargar un bloque en
un caché totalmente ocupado: Hay que eliminar algún bloque y volverlo a
escribir en el disco en caso de que haya sido modificado luego de haberlo traído
del disco. Se plantea una situación muy parecida a la paginación y se resuelve
con algoritmos similares. Se debe considerar la posibilidad de una falla total del
sistema y su impacto en la consistencia del sistema de archivos: Si un bloque
crítico, como un bloque de un nodo-i, se lee en el caché y se modifica, sin
volverse a escribir en el disco, una falla total del sistema dejará al sistema de
archivos en un estado inconsistente. Se deben tener en cuenta los siguientes
factores: ¿ Es posible que el bloque modificado se vuelva a necesitar muy pronto
?: Los bloques que se vayan a utilizar muy pronto, como un bloque parcialmente
ocupado que se está escribiendo, deberían permanecer un “largo tiempo”. ¿ Es
esencial el bloque para la consistencia del sistema de archivos ?: Si es esencial
(generalmente lo será si no es bloque de datos) y ha sido modificado, debe
escribirse en el disco de inmediato: Se reduce la probabilidad de que una falla
total del sistema haga naufragar al sistema de archivos. Se debe elegir con
cuidado el orden de escritura de los bloques críticos. No es recomendable
mantener los bloques de datos en el caché durante mucho tiempo antes de
reescribirlos. La solución de algunos S. O. consiste en tener una llamada al
sistema que fuerza una actualización general a intervalos regulares de algunos
segundos (por ej. 30). Otra solución consiste en escribir los bloques modificados
(del caché) al disco, tan pronto como haya sido escrito (el caché):
Se dice que se trata de cachés de escritura. Requiere más e / s que otros tipos
de cachés. Una técnica importante para aumentar el rendimiento de un sistema
de archivos es la reducción de la cantidad de movimientos del brazo del disco
(mecanismo de acceso): Se deben colocar los bloques que probablemente
tengan un acceso secuencial, próximos entre sí, preferentemente en el mismo
cilindro. Los nodos-i deben estar a mitad del disco y no al principio, reduciendo a
la mitad el tiempo promedio de búsqueda entre el nodo-i y el primer bloque del
archivo. Inicio: Fin: Descriptor de Archivos
El descriptor de archivos o bloque de control de archivos es un bloque de control
que contiene información que el sistema necesita para administrar un archivo [7,
Deitel].
Es una estructura muy dependiente del sistema.
Puede incluir la siguiente información:
Nombre simbólico del archivo. Localización del archivo en el almacenamiento
secundario. Organización del archivo (método de organización y acceso). Tipo
de dispositivo. Datos de control de acceso. Tipo (archivo de datos, programa
objeto, programa fuente, etc.). Disposición (permanente contra temporal). Fecha
y tiempo de creación. Fecha de destrucción. Fecha de la última modificación.
Suma de las actividades de acceso (número de lecturas, por ejemplo). Los
descriptores de archivos suelen mantenerse en el almacenamiento secundario;
se pasan al almacenamiento primario al abrir el archivo. El descriptor de
archivos es controlado por el sistema de archivos; el usuario puede no hacer
referencia directa a él.
Inicio: Fin:
Seguridad
Los sistemas de archivos generalmente contienen información muy valiosa para
sus usuarios, razón por la que los sistemas de archivos deben protegerla [23,
Tanenbaum].
El Ambiente de Seguridad
Se entenderá por seguridad a los problemas generales relativos a la garantía de
que los archivos no sean leídos o modificados por personal no autorizado; esto
incluye aspectos técnicos, de administración, legales y políticos.
Se consideraran mecanismos de protección a los mecanismos específicos del
sistema operativo utilizados para resguardar la información de la computadora.
La frontera entre seguridad y mecanismos de protección no está bien definida.
Dos de las más importantes facetas de la seguridad son:
La pérdida de datos. Los intrusos. Algunas de las causas más comunes de la
pérdida de datosson: Actos y hechos diversos, como incendios, inundaciones,
terremotos, guerras, revoluciones, roedores, etc. Errores de hardware o de
software, como fallas en la cpu, discos o cintas ilegibles, errores de
telecomunicación, errores en los programas, etc. Errores humanos, por ej.,
entrada incorrecta de datos, mal montaje de cintas o discos, ejecución incorrecta
de programas, pérdida de cintas o discos, etc. La mayoría de estas causas se
pueden enfrentar con el mantenimiento de los respaldos (back-ups) adecuados;
debería haber copias en un lugar alejado de los datos originales. Respecto del
problema de los intrusos, se los puede clasificar como:
Pasivos: solo desean leer archivos que no están autorizados a leer. Activos:
desean hacer cambios no autorizados a los datos. Para diseñar un sistema
seguro contra intrusos: Hay que tener en cuenta el tipo de intrusos contra los
que se desea tener protección. Hay que ser consciente de que la cantidad de
esfuerzo que se pone en la seguridad y la protección depende claramente de
quién se piensa sea el enemigo. Algunos tipos de intrusos son los siguientes:
Curiosidad casual de usuarios no técnicos. Conocidos (técnicamente
capacitados) husmeando. Intentos deliberados por hacer dinero. Espionaje
comercial o militar. Otro aspecto del problema de la seguridad es la privacía:
Protección de las personas respecto del mal uso de la información en contra de
uno mismo. Implica aspectos legales y morales. También debe señalarse la
posibilidad del ataque del caballo de Troya: Modificar un programa normal para
que haga cosas adversas además de su función usual. Arreglar las cosas para
que la víctima utilice la versión modificada. Además debe considerarse la
posibilidad de ataques al estilo del gusano de Internet: Fue liberado por Robert
Tappan Morris el 02/11/88 e hizo que se bloquearan la mayoría de los sistemas
Sun y Vax de Internet (fue descubierto y condenado). Constaba de un programa
arrancador y del gusano propiamente dicho. Utilizaba fallas se seguridad del
Unix y de los programas Finger y Sendmail de Internet. Una forma de probar la
seguridad de un sistema es contratar un grupo de expertos en seguridad,
conocido como el equipo tigre o equipo de penetración, cuyo objetivo es intentar
penetrar el sistema de seguridad para descubrir sus falencias y proponer
soluciones. Otro aspecto importante de la seguridad consiste en no subestimar
los problemas que puede causar el personal.
Inicio: Fin:
Virus
Los virus computacionales:
Constituyen una categoría especial de ataque. Son un enorme problema para
muchos usuarios. Son fragmentos de programas que se añaden a programas
legítimos con la intención de infectar a otros. Un virus difiere de un gusano en lo
siguiente: Un virus está a cuestas de un programa existente. Un gusano es un
programa completo en sí mismo. Los virus y los gusanos intentan diseminarse y
pueden crear un daño severo. Generalmente se propagan a través de copias
ilegítimas de programas. Comúnmente los virus se ejecutan e intentan
reproducirse cada vez que se ejecuta el programa que los aloja. Frecuentemente
los problemas con los virus son más fáciles de evitar que de curar: Utilizar
software original adquirido en comercios respetables. No utilizar copias “piratas”.
Efectuar controles rigurosos y frecuentes con programas antivirus actualizados.
Trabajar con metodología y disciplina rigurosa en el intercambio de discos y en
las copias a través de redes de comunicación de datos. Inicio: Fin: Principios del
Diseño Para la Seguridad
El diseño del sistema debe ser público, ya que pensar que el intruso no
conocerá la forma de funcionamiento del sistema es un engaño.
El estado predefinido debe ser el de no acceso, dado que los errores en donde
se niega el acceso válido se reportan más rápido que los errores en donde se
permite el acceso no autorizado.
Verificar la autorización actual :
El sistema no debe: Verificar el permiso. Determinar que el acceso está
permitido. Abandonar esta información para su uso posterior. El sistema
tampoco debe: Verificar el permiso al abrir un archivo y no después de abrirlo,
pues un acceso habilitado permanecería como válido aunque haya cambiado la
protección del archivo. Dar a cada proceso el mínimo privilegio posible, lo que
implica un esquema de “protección de grano fino”. El mecanismo de protección
debe ser simple, uniforme e integrado hasta las capas más bajas del sistema:
Dotar de seguridad a un sistema inseguro es casi imposible. La seguridad no es
una característica que se pueda añadir fácilmente. El esquema de seguridad
debe ser sicológicamente aceptable: Los usuarios no deben sentir que la
protección de sus archivos les implica demasiado trabajo: Podrían dejar de
proteger sus archivos. Se quejarían en caso de problemas. No aceptarían
fácilmente su propia culpa. Inicio: Fin: Autentificación del Usuario
Muchos esquemas de protección se basan en la hipótesis de que el sistema
conoce la identidad de cada usuario.
La identificación de los usuarios se conoce como la autentificación de los
usuarios.
Muchos métodos de autentificación se basan en:
La identificación de algo conocido por el usuario. Algo que posee el usuario.
Algo que es el usuario. Inicio: Fin: Contraseñas
Son la forma de autentificación más utilizada.
Son de fácil comprensión e implementación.
Deben almacenarse cifradas (encriptadas).
Se deben prever intentos de penetración consistentes en pruebas de
combinaciones de nombres y contraseñas.
Si las contraseñas fueran de 7 caracteres elegidos al azar de los 95 caracteres
ASCII que se pueden imprimir:
El espacio de búsqueda sería de 95 7 , alrededor de 7 x 10 13 . A 1.000
ciframientos por segundo tomaría 2.000 años construir la lista a verificar contra
el archivo de contraseñas. Una mejora al esquema de contraseñas consiste en:
Asociar un número aleatorio de “n” bits a cada contraseña. El número aleatorio
se modifica al cambiar la contraseña. El número se guarda en el archivo de
contraseñas en forma no cifrada. Se concatenan la contraseña y el número
aleatorio y se cifran juntos. El resultado cifrado se almacena en el archivo de
contraseñas. Se aumenta por 2 n el espectro de búsqueda: a esto se llama salar
el archivo de contraseñas. Una protección adicional consiste en hacer ilegible el
archivo de contraseñas encriptadas. Otra protección adicional consiste en que el
sistema sugiera a los usuarios contraseñas generadas según ciertos criterios;
con esto se evita que el usuario elija contraseñas muy sencillas.
También es conveniente que el sistema obligue al usuario a cambiar sus
contraseñas con regularidad; se puede llegar a la contraseña de una sola vez.
Una variante de la idea de contraseña es solicitar al usuario respuestas sobre
información de contexto que debe conocer.
Otra variante es la de reto-respuesta:
Se acuerdan con el usuario algoritmos (por ejemplo formulas matemáticas) que
se utilizarán según el día y / o la hora. Cuando el usuario se conecta: El sistema
suministra un argumento. El usuario debe responder con el resultado
correspondiente al algoritmo vigente ese día a esa hora. Inicio: Fin: Identificación
Física
Una posibilidad es la verificación de si el usuario tiene cierto elemento
(generalmente una tarjeta plástica con una banda magnética), que generalmente
se combina con una contraseña.
Otro aspecto consiste en la medición de características físicas difíciles de
reproducir:
Huellas digitales o vocales. Firmas. Longitud de los dedos de las manos. Inicio:
Fin: Medidas Preventivas
Limitar los intentos de acceso fallidos y registrarlos.
Registrar todos los accesos.
Tender trampas para atrapar a los intrusos.
Inicio: Fin:
Mecanismos de Protección
Dominios de Protección
Muchos objetos del sistema necesitan protección, tales como la cpu, segmentos
de memoria, unidades de disco, terminales, impresoras, procesos, archivos,
bases de datos, etc. [23, Tanenbaum].
Cada objeto se referencia por un nombre y tiene habilitadas un conjunto de
operaciones sobre él.
Un dominio es un conjunto de parejas (objeto, derechos):
Cada pareja determina: Un objeto. Un subconjunto de las operaciones que se
pueden llevar a cabo en él. Un derecho es el permiso para realizar alguna de las
operaciones. Es posible que un objeto se encuentre en varios dominios con
“distintos” derechos en cada dominio.
Un proceso se ejecuta en alguno de los dominios de protección:
Existe una colección de objetos a los que puede tener acceso. Cada objeto tiene
cierto conjunto de derechos. Los procesos pueden alternar entre los dominios
durante la ejecución. Una llamada al S. O. provoca una alternancia de dominio.
En algunos S. O. los dominios se llaman anillos.
Una forma en la que el S. O. lleva un registro de los objetos que pertenecen a
cada dominio es mediante una matriz :
Los renglones son los dominios. Las columnas son los objetos. Cada elemento
de la matriz contiene los derechos correspondientes al objeto en ese dominio,
por ej.: leer, escribir, ejecutar. Inicio: Fin: Listas Para Control de Acceso
Las “matrices de protección” son muy grandes y con muchos lugares vacíos [23,
Tanen-baum]:
Desperdician espacio de almacenamiento. Existen métodos prácticos que
almacenan solo los elementos no vacíos por filas o por columnas. La lista de
control de acceso (ACL: access control list): Asocia a cada objeto una lista
ordenada con: Todos los dominios que pueden tener acceso al objeto. La forma
de dicho acceso (ej: lectura ®, grabación (w), ejecución (x)). Una forma de
implementar las ACL consiste en: Asignar tres bits (r, w, x) para cada archivo,
para: El propietario, el grupo del propietario y los demás usuarios. Permitir que el
propietario de cada objeto pueda modificar su ACL en cualquier momento:
Permite prohibir accesos antes permitidos. Inicio: Fin: Posibilidades
La matriz de protección también puede dividirse por renglones [23, Tanenbaum]:
Se le asocia a cada proceso una lista de objetos a los cuales puede tener
acceso. Se le indican las operaciones permitidas en cada uno. Esto define su
dominio. La lista de objetos se denomina lista de posibilidades y los elementos
individuales se llaman posibilidades. Cada posibilidad tiene:
Un campo tipo: Indica el tipo del objeto. Un campo derechos: Mapa de bits que
indica las operaciones básicas permitidas en este tipo de objeto. Un campo
objeto: Apuntador al propio objeto (por ej.: su número de nodo-i). Las listas de
posibilidades son a su vez objetos y se les puede apuntar desde otras listas de
posibilidades; esto facilita la existencia de subdominios compartidos. Las listas
de posibilidades o listas-c deben ser protegidas del manejo indebido por parte
del usuario.
Los principales métodos de protección son:
Arquitectura marcada: Necesita un diseño de hardware en el que cada palabra
de memoria tiene un bit adicional: Indica si la palabra contiene una posibilidad o
no. Solo puede ser modificado por el S. O. Lista de posibilidades dentro del S.
O.: Los procesos hacen referencia a las posibilidades mediante su número. Lista
de posibilidades cifrada dentro del espacio del usuario: Cada posibilidad está
cifrada con una clave secreta desconocida por el usuario. Muy adecuado para
sistemas distribuidos. Generalmente las posibilidades tienen derechos genéricos
aplicables a todos los objetos, por ej.: Copiar posibilidad: Crear una nueva
posibilidad para el mismo objeto. Copiar objeto: Crear un duplicado del objeto
con una nueva posibilidad. Eliminar posibilidad: Eliminar un dato dentro de la
lista-c sin afectar al objeto. Destruir objeto: Eliminar en forma permanente un
objeto y una posibilidad. Muchos sistemas con posibilidades se organizan como
una colección de módulos con módulos administradores de tipos para cada tipo
de objeto y entonces es esencial que el módulo administrador de tipos pueda
hacer más cosas con la posibilidad que un proceso ordinario. Se utiliza la técnica
de amplificación de derechos:
Los administradores de tipo obtienen una plantilla de derechos que les da más
derechos sobre un objeto de los que permitía la propia lista de posibilidades.
Inicio: Fin: Modelos de Protección
Las matrices de protección no son estáticas sino dinámicas[23, Tanenbaum].
Se pueden identificar seis operaciones primitivas en la matriz de protección:
Crear objeto. Eliminar objeto. Crear dominio. Eliminar dominio. Insertar derecho.
Eliminar derecho. Las primitivas se pueden combinar en comandos de
protección, que pueden ser ejecutados por los programas del usuario para
modificar la matriz de protección. En cada momento, la matriz de protección
determina lo que puede hacer un proceso en cualquier momento; no determina
lo que no está autorizado a realizar.
La matriz es impuesta por el sistema.
La autorización tiene que ver con la política de administración.
Inicio: Fin:
Control de Acceso Por Clases de Usuarios
Una matriz de control de acceso puede llegar a ser tan grande que resulte
impráctico mantenerla [7, Deitel].
Una técnica que requiere menos espacio es controlar el acceso a varias clases
de usuarios.
Un ejemplo de esquema de clasificación es el siguiente:
Propietario: Suele ser el usuario que creó el archivo. Usuario especificado: El
propietario especifica quién más puede usar el archivo. Grupo o proyecto: Los
diferentes miembros de un grupo de trabajo sobre un proyecto, acceden a los
diferentes archivos relacionados con el proyecto. Público: Un archivo público
puede ser accedido por cualquier usuario de la computadora. Generalmente
permite leer o ejecutar pero no escribir sobre el archivo. Inicio: Fin: Respaldo y
Recuperación
La destrucción de la información, ya sea accidental o intencional, es una realidad
y tiene distintas causas [7, Deitel]:
Fallas de hardware y de software. Fenómenos meteorológicos atmosféricos.
Fallas en el suministro de energía. Incendios e inundaciones. Robos, vandalismo
(incluso terrorismo). Etc. Esta posible destrucción de la información debe ser
tenida en cuenta por: Los sistemas operativos en general. Los sistemas de
archivos en particular. Una técnica muy usada para asegurar la disponibilidad de
los datos es realizar respaldos periódicos: Hacer con regularidad una o más
copias de los archivos y colocarlas en lugar seguro. Todas las actualizaciones
realizadas luego del último respaldo pueden perderse. Otra técnica es pasar
todas las transacciones a un archivo, copiándolas en otro disco: Genera una
redundancia que puede ser costosa. En caso de fallas en el disco principal,
puede reconstruirse todo el trabajo perdido si el disco de reserva no se dañó
también. También existe la posibilidad del respaldo incremental : Durante una
sesión de trabajo los archivos modificados quedan marcados. Cuando un
usuario se retira del sistema (deja de trabajar), un proceso del sistema efectúa el
respaldo de los archivos marcados. Se debe tener presente que es muy difícil
garantizar una seguridad absoluta de los archivos.
5.1.1 Dispositivos de Io
5.1.2 Controladores de Dispositivos
5.2 Principios de Software de I O
5.2.1 Objetivos del Software de IO
5.2.2 Manejadores de Interrupciones
5.2.3 Manejador de Dispositivos
5.2.4 Software de Io independiente de Dispositivos
5.2.5 Espacio del Usuario para Software de IO
5.3 Discos Ram
5.4 Discos Duros
5.4.1 Hardware de Discos
5.4.2 Software para Discos
5.5 Relojes
5.5.1 Hardware de discos
5.5.2 Software Reloj
5.5.3 Manejador del Reloj
5.6 Terminales
5.6.1 Hardware de Terminales
5.6.2 Manejadores
Unidad 6 Administrador de archivos
6.1 Sistema de Archivos
6.2 Jerarquia de Datos
6.3 Tipos de Archivos
6.4 Interfase con Usuario
6.4.1 El Sistema de Archivo visto por el usuario
6.4.2 Diseño del Sistema de Archivos
6.4.3 Servidor de Archivos
6.4.4 Seguridad en Archivos
6.4.5 Mecanismos de Proteccion de Archivos
6.4.6 Implementacion Sistemas de Archivos
6.5 Llamadas al Sistema System Calls
6.6 Tipos de Interfaz
6.7 Lenguaje de Comunicacion (comandosdecontrol) y pipelines o conductos
Unidad 7 Desempeño y seguridad
7.1 Medicion Desempeño Performance Sistemas Operativos , monitoreo y
evaluación
7.2 Seguridad de Sistemas Operativos
7.2.1 Conceptos Fundamentales de Seguridad Sistemas Operativos
7.2.2 Vigilancia Sistemas Operativos
7.2.3 Proteccion Sistemas Operativos
7.2.4 Auditoria Sistemas Operativos
7.2.5 Controles de Acceso Sistemas Operativos
7.2.6 Nucleos de Seguridad Sistemas Operativos
7.2.7 Seguridad por Hardware y Software
7.2.8 Criptografia Sistemas Operativos
7.2.9 Penetracion Sistema Operativo
Documentos relacionados
Descargar