Monografias | Arquitectura del Sistema Operativo Windows NT

Arquitectura del Sistema Operativo Windows NT

Resumen: Introducción y conceptos básicos. Diseño de Windows NT. Procesos. Administración de la memoria. Sistema de archivos. Entrada y salida. Windows NT 5.

Publicación enviada por Saul Gonzales


 

Indice
1. Prólogo
2. Introducción Y Conceptos Básicos
3. Diseño de Windows Nt
4. Procesos
5. Administración de la Memoria
6. Sistema de Archivos
7. Entrada y Salida
8. Windows Nt 5
9. Bibliografia

 

1. Prólogo

El presente trabajo trata sobre la Arquitectura de Windows NT. La investigación se ha llevado a cabo desde cuatro puntos de vista que son los componentes señalados por Andrew Tanenbaum para el enfoque del estudio de un Sistema Operativo, es decir: procesos, administración de la memoria, ficheros y entrada/salida. Se ha comenzado con un capítulo dedicado a conceptos básicos y otro a la arquitectura global del sistema, para seguidamente estudiar en detalle cada uno de los cuatro puntos antes citados.

Se puede decir que Windows NT representa la primera propuesta de la empresa Microsoft por construir un Sistema Operativo serio, capaz de competir con los dinosaurios clásicos como UNIX o VMS (o al menos intentarlo). Para ello se ha elegido un enfoque cliente-servidor, con la intención de alcanzar el sueño delos Sistemas Distribuidos.

Windows NT no se puede considerar todavía un sistema operativo de carácter doméstico. Pero el objetivo de sus diseñadores parece ser que lo sea dentro de muy pocos años, y de hecho, para que los programadores vayan entreteniéndose en el uso de las llamadas al sistema (el llamado Win32), han construido un Sistema Operativo de poco confiable. Hablamos, cómo no, deWindows 95.

La arquitectura de Windows 95/98 no tiene absolutamente nada que ver con la de Windows NT. No es que sea un mal trabajo pero deja bastante que desear.

Durante la elaboración de este trabajo nos hemos encontrado con varias dificultades principalmente por la falta de fuentes bibliográficas que trataran el diseño con la suficiente profundidad como para satisfacer el nivel que se buscaba. Los libros que se encontraron, la mayoría se refieren a la Administración del Sistema a alto nivel, o bien de la programación bajo Windows NT en lenguaje C++, por lo que he tenido que recurrir a diversos artículos de la Internet, principalmente al nodo de Microsoft en Internet. Por ello, pedimos disculpas por las posibles erratas que puedan existir.

Para tratar ciertos temas dentro de cada capítulo se ha creídoconveniente apoyarnos en la descripción de las llamadas al sistema, ya que, anuestro entender, de esta manera todo resulta mucho más fácil de explicar y decomprender.

 

2. Introduccion Y Conceptos Basicos

Eventos A Través Del Tiempo

A finales de los años 40's y a principios de los años 50's las computadorasmasivas, eran controladas por tubos al vacío inestables. Todo la programaciónse hacía directamente en lenguaje de máquina porque la industria no habíaavanzado lo suficiente para necesitar Sistemas Operativos. Con la aparición deltransistor a mediados de los 50's, las computadoras se fueron haciendo más y másconfiables.

Lenguajes crudos como Ensamblador y Fortran aparecieron, pero un SistemaOperativo (S.O.), tal como los conocemos ahora, aún no. Para accesar a laprogramación de la maquinaria se manejaron tarjetas perforadas.

1960's. Cuando IBM introdujo la computadora System/360 intentó tomar elmercado científico y el comercial. Cuando en este proyecto surgieron problemasde conflictos por la arquitectura, se inició el desarrollo de un software queresolviera todos aquellos conflictos, el resultado fue un muy complejo sistemaoperativo. Luego AT&T trató de desarrollar a Multics, un Sistema Operativoque soportara cientos de usuarios de tiempo compartido, pero falló. Másadelante científicos de la computación desarrollaron Unics, que seríamonousuario. Ello marca el nacimiento de Unix (1969), el primero de los sistemasoperativos modernos.

1980's. En este tiempo la arquitectura de las computadoras, circuitos LSI(Large Scale Integration) abrieron el paso para una nueva generación decomputadoras. DOS de Microsoft aparece en 1981 dominando este mercado de las PCsinmediatamente, aunque el sistema UNIX, predomina en las estaciones de trabajo.

1990's. Aumenta el uso de conexiones en redes, equipos de trabajo yaplicaciones distribuidas, los cuales surgen en la década anterior, con ellolos Sistemas Operativos como Unix, Windows NT, etc., soportan muchos clientes,dando así el nacimiento de la Computación en Red.

Sistema Operativo

Introducción

Software básico que controla y administra los recursos deuna computadora. El sistema operativo tiene tres grandes funciones: coordina ymanipula el hardware de la computadora, como la memoria, las impresoras, lasunidades de disco, el teclado o el mouse; organiza los archivos en diversosdispositivos de almacenamiento, como discos flexibles, discos duros, discoscompactos o cintas magnéticas, y gestiona los errores de hardware y la pérdidade datos.

¿Cómo funciona un sistema operativo?

Los Sistemas Operativos controlan diferentes procesos de lacomputadora. Un proceso importante es la interpretación de los comandos quepermiten al usuario comunicarse con el ordenador. Algunos intérpretes deinstrucciones están basados en texto y exigen que las instrucciones seantecleadas. Otros están basados en gráficos, y permiten al usuario comunicarseseñalando y haciendo clic en un icono.

Los Sistemas Operativos pueden ser de tarea única omultitarea. Los sistemas operativos de tarea única, más primitivos, sólopueden manejar un proceso en cada momento. Por ejemplo, cuando la computadoraestá imprimiendo un documento, no puede iniciar otro proceso ni responder anuevas instrucciones hasta que se termine la impresión.

Todos los Sistemas Operativos modernos son multitarea ypueden ejecutar varios procesos simultáneamente. En la mayoría de losordenadores sólo hay una UCP; un Sistema Operativo multitarea crea la ilusiónde que varios procesos se ejecutan simultáneamente en la UCP. El mecanismo quese emplea más a menudo para lograr esta ilusión es la multitarea porsegmentación de tiempos, en la que cada proceso se ejecuta individualmentedurante un periodo de tiempo determinado. Si el proceso no finaliza en el tiempoasignado, se suspende y se ejecuta otro proceso. Este intercambio de procesos sedenomina conmutación de contexto. El sistema operativo se encarga de controlarel estado de los procesos suspendidos. También cuenta con un mecanismo llamadoplanificador que determina el siguiente proceso que debe ejecutarse. Elplanificador ejecuta los procesos basándose en su prioridad para minimizar elretraso percibido por el usuario. Los procesos parecen efectuarse simultáneamentepor la alta velocidad del cambio de contexto.

Los Sistemas Operativos pueden emplear memoria virtual paraejecutar procesos que exigen más memoria principal de la realmente disponible.Con esta técnica se emplea espacio en el disco duro para simular la memoriaadicional necesaria.

Sistemas Operativos actuales

Los sistemas operativos empleados normalmente son UNIX,Macintosh OS, MS-DOS, OS/2 y Windows-NT. El UNIX y sus clones permiten múltiplestareas y múltiples usuarios. Su sistema de archivos proporciona un métodosencillo de organizar archivos y permite la protección de archivos. Sinembargo, las instrucciones del UNIX no son intuitivas. Otros sistemas operativosmultiusuario y multitarea son OS/2, desarrollado inicialmente por MicrosoftCorporation e International Business Machines (IBM) y Windows-NT, desarrolladopor Microsoft. El sistema operativo multitarea de las computadoras Apple sedenomina Macintosh OS. El DOS y su sucesor, el MS-DOS, son sistemas operativospopulares entre los usuarios de computadoras personales. Sólo permiten unusuario y una tarea.

Sistema Operativo de Red

A un Sistema Operativo de Red se le conoce como NOS. Es elsoftware necesario para integrar los muchos componentes de una red en un sistemaparticular, al cual el usuario final puede tener acceso.

Otra definición es la siguiente; es un software que rige yadministra los recursos, archivos, periféricos, usuarios, etc., en una red ylleva el control de seguridad de los mismos.

Un NOS maneja los servicios necesarios para asegurar que elusuario final tenga o esté libre de error al accesar a la red. Un NOSnormalmente provee una interfaz de usuario que es para reducir la complejidad yconflictos al momento de usar la red.

Dentro del contexto del Sistema Operativo de Red, se puedenescribir aplicaciones tales como un sistema de correo electrónico pueden serescritas para que permitan "conexiones virtuales" entre entidades dered, sin intervención humana directa.

Diferencia entre un S.O. Distribuido, un S.O. de Red y unS.O. Centralizado.

En un Sistema Operativo de Red, los usuarios saben de laexistencia de varias computadoras y pueden conectarse con máquinas remotas ycopiar archivos de una máquina a otra, cada máquina ejecuta su propio sistemaoperativo local y tiene su propio usuario o grupo de usuarios.

Por el contrario, un Sistema Operativo Distribuido es aquelque aparece ante sus usuarios como un sistema tradicional de un solo procesador,aun cuando esté compuesto por varios procesadores. En un sistema distribuidoverd adero, los usuarios no deben saber del lugar donde su programa se ejecute odel lugar donde se encuentran sus archivos; eso debe ser manejado en forma automáticay eficaz por el Sistema Operativo.

Además son sistemas autónomos capaces de comunicarse ycooperar entre sí para resolver tareas globales. Es indispensable el uso deredes para intercambiar datos. Además de los servicios típicos de un SistemaOperativo, un Sistema Distribuido debe gestionar la distribución de tareasentre los diferentes nodos conectados. También, debe proporcionar losmecanismos necesarios para compartir globalmente los recursos del sistema.

Sistemas Operativos Centralizados, de un solo procesador, deun solo CPU o incluso tradicionales; en todo caso, lo que esto quiere decir esque un sistema operativo controla una sola computadora.

 

3. Diseño De Windows Nt

Windows NT presenta una arquitectura del tipocliente-servidor. Los programas de aplicación son contemplados por el sistemaoperativo como si fueran clientes a los que hay que servir, y para lo cual vieneequipado con distintas entidades servidoras.

Uno de los objetivos fundamentales de diseño fue el tener unnúcleo tan pequeño como fuera posible, en el que estuvieran integrados módulosque dieran respuesta a aquellas llamadas al sistema que necesariamente setuvieran que ejecutar en modo privilegiado (también llamado modo kernel, modo núcleoy modo supervisor). El resto de las llamadas se expulsarían del núcleo haciaotras entidades que se ejecutarían en modo no privilegiado (modo usuario), y deesta manera el núcleo resultaría una base compacta, robusta y estable. Por esose dice que Windows NT es un sistema operativo basado en micro-kernel.

Es por ello que en un primer acercamiento a la arquitecturadistinguimos un núcleo que se ejecuta en modo privilegiado, y se denominaExecutive, y unos módulos que se ejecutan en modo no privilegiado, llamadossubsistemas protegidos.

Los programas de usuario (también llamados programas deaplicación) interaccionan con cualquier sistema operativo (SO) a través de unjuego de llamadas al sistema, que es particular de cada SO. En el mundo Windowsen general, las llamadas al sistema se denominan API (Application ProgrammingInterfaces, interfaces para la programación de aplicaciones). En Windows NT yen Windows 95 se usa una versión del API llamada API Win32. Un programa escritopara Windows NT o Windows 95, y que por consiguiente hace uso del API Win32, sedenomina genéricamente "programa Win32", y de hecho esta denominaciónes bastante frecuente en artículos y libros al respecto. Desgraciadamente, yconviene dejarlo claro cuanto antes, el término "Win32" tiene tresacepciones (al menos hasta ahora) totalmente distintas. Una es el API, otra esel nombre de uno de los subsistemas protegidos de Windows NT del que hablaremosmás adelante, y por último se denomina Win32s a una plataforma desarrolladapor Microsoft, similar a Windows 3.1, pero que usa el API Win32 en vez del APIWin16 del Windows 3.1.

Hechas estas aclaraciones, podemos continuar adelante.Algunas de las llamadas al sistema, debido a su naturaleza, son atendidasdirectamente por el Executive, mientras que otras son desviadas hacia algúnsubsistema. Esto lo veremos con detalle en breve.

El hecho de disponer de un núcleo rodeado de subsistemas quese ejecutan en modo usuario nos permite además añadir nuevos subsistemas sinproducir ningún tipo de confrontación.

En el diseño de Windows NT han confluido aportaciones detres modelos: el modelo cliente-servidor, el modelo de objetos, y el modelo demultiprocesamiento simétrico.

Modelo cliente-servidor. En la teoría de este modelo seestablece un kernel que básicamente se encarga de recibir peticiones deprocesos clientes y pasárselas a otros procesos servidores, ambos clientes yservidores ejecutándose en modo usuario. Windows NT pone el modelo en prácticapero no contempla el núcleo como un mero transportador de mensajes, sino queintroduce en él aquellos servicios que sólo pueden ser ejecutados en modokernel. El resto de servicios los asciende hacia subsistemas servidores que seejecutan en modo usuario, independientes entre sí, y que por tanto puedenrepartirse entre máquinas distintas, dando así soporte a un sistemadistribuido (de hecho, el soportar los sistemas distribuidos fue otra de lasgrandes directivas de diseño de este SO).

Modelo de objetos. Decir que no implementa puramente la teoríade este modelo, sino que más bien lo que hace es simplemente contemplar losrecursos (tanto internos como externos) como objetos. Más adelante daremos unalista de los objetos de Windows NT. Brevemente, señalar que todo objeto ha deposeer identidad propia (es único y distinguible de todos los demás), y unaserie de atributos (variables) y métodos (funciones) que modifican susatributos. Los objetos interaccionan entre sí a través del envío de mensajes.No sólo existen en Windows NT objetos software (lógicos), sino que losdispositivos hardware (físicos) también son tratados como objetos (adiferencia de UNIX, que recordemos trataba a los dispositivos como ficheros).

Modelo de multiprocesamiento simétrico. Un SO multiproceso(o sea, aquel que cuenta con varias CPU y cada una puede estar ejecutando unproceso) puede ser simétrico (SMP) o asimétrico (ASMP). En los sistemasoperativos SMP (entre los que se encuentran Windows NT y muchas versiones deUNIX) cualquier CPU puede ejecutar cualquier proceso, ya sea del SO o no,mientras que en los ASMP se elige una CPU para uso exclusivo del SO y el restode CPU quedan para ejecutar programas de usuario. Los sistemas SMP son máscomplejos que los ASMP, contemplan un mejor balance de la carga y son mástolerantes a fallos (de manera que si un subproceso del SO falla, el SO no secaerá pues podrá ejecutarse sobre otra CPU, cosa que en los ASMP no seríaposible, con lo que se bloquearía el sistema entero).

Comencemos describiendo los subsistemas protegidos, paraseguidamente estudiar la estructura del Executive.

Figura 1. El núcleo se ejecuta en modo privilegiado(Executive) y en modo no privilegiado (subsistemas protegidos)

Los Subsistemas Protegidos

Son una serie de procesos servidores que se ejecutan en modousuario como cualquier proceso de usuario, pero que tienen algunas característicaspropias que los hacen distintos. Al decir subsistemas protegidos nosreferiremos, pues, a estos procesos. Se inician al arrancar el SO. Los hay dedos tipos: integrales y de entorno.

Un Subsistema Integral: es aquel servidor que ejecuta unafunción crítica del SO (como por ejemplo el que gestiona la seguridad).Tenemos los siguientes:

El Subsistema Proceso de Inicio (Logon Process)

El proceso de inicio (Logon Process) recibe las peticiones deconexión por parte de los usuarios. En realidad son dos procesos, cada unoencargándose de un tipo distinto de conexión:

El proceso de inicio local: gestiona la conexión de usuarios localesdirectamente a una máquina Windows NT.

El proceso de inicio remoto: gestiona la conexión de usuarios remotos aprocesos servidores de Windows NT.

Figura 2. Diagrama de Flujo del Proceso de Inicio de Windows NT.

El Subsistema de Seguridad

Este subsistema interacciona con el proceso de inicio y elllamado monitor de referencias de seguridad (se tratara en el Executive), y deesta forma se construye el modelo de seguridad en Windows NT.

El subsistema de seguridad interacciona con el proceso deinicio, atendiendo las peticiones de acceso al sistema. Consta de dossubcomponentes:

La autoridad de seguridad local: es el corazón delsubsistema. En general gestiona la política de seguridad local; así, seencarga de generar los permisos de acceso, de comprobar que el usuario quesolicita conexión tiene acceso al sistema, de verificar todos los accesos sobrelos objetos (para lo cual se ayuda del monitor de referencias a seguridad) y decontrolar la política de auditorías, llevando la cuenta de los mensajes deauditoría generados por el monitor de referencias. Las auditorías son unafacilidad que proporciona Windows NT para monitorizar diversos acontecimientosdel sistema por parte del Administrador.

El administrador de cuentas: mantiene una base de datos con las cuentas detodos los usuarios (login, claves, identificaciones, etc.). Proporciona losservicios de validación de usuarios requeridos por el subcomponente anterior.

Un Subsistema de Entorno: da soporte a aplicacionesprocedentes de SO distintos, adaptándolas para su ejecución bajo Windows NT.Existen tres de este tipo:

El Subsistema Win32

Es el más importante, ya que atiende no sólo a las aplicaciones nativas deWindows NT, sino que para aquellos programas no Win32, reconoce su tipo y loslanza hacia el subsistema correspondiente. En el caso de que la aplicación seaMS-DOS o Windows de 16 bits (Windows 3.11 e inferiores), lo que hace es crear unnuevo subsistema protegido pero no servidor. Así, la aplicación DOS o Win16 seejecutaría en el contexto de un proceso llamado VDM (Virtual DOS Machine, máquinavirtual DOS), que no es más que un simulador de un ordenador funcionando bajoMS-DOS. Las llamadas al API Win16 serían correspondidas con las homónimas enAPI Win32. Microsoft llama a esto WOW (Windows On Win32).

El subsistema soporta una buena parte del API Win32. Así, seencarga de todo lo relacionado con la interfaz gráfica con el usuario (GUI),controlando las entradas del usuario y salidas de la aplicación. Por ejemplo,un buen número de funciones de las bibliotecas USER32 y GDI32 son atendidas porWin32, ayudándose del Executive cuando es necesario.

El funcionamiento como servidor de Win32 lo veremos un poco másadelante, en el apartado de llamadas a procedimientos locales.

El Subsistema POSIX

La norma POSIX (Portable Operating System Interface for Unix)fue elaborada por IEEE para conseguir la portabilidad de las aplicaciones entredistintos entornos UNIX. La norma se ha implementado no sólo en muchasversiones de UNIX, sino también en otros SO como Windows NT, VMS, etc. Se tratade un conjunto de 23 normas, identificadas como IEEE 1003.0 a IEEE 1003.22, otambién POSIX.0 a POSIX.22, de las cuales el subsistema POSIX soporta laPOSIX.1, que define un conjunto de llamadas al sistema en lenguaje C.

El subsistema sirve las llamadas interaccionando con elExecutive. Se encarga también de definir aspectos específicos del SO UNIX,como pueden ser las relaciones jerárquicas entre procesos padres e hijos (lascuales no existen en el subsistema Win32, por ejemplo, y que por consiguiente noaparecen implementadas directamente en el Executive).

El Subsistema OS/2

Igual que el subsistema POSIX proporciona un entorno para aplicaciones UNIX,este subsistema da soporte a las aplicaciones OS/2. Proporciona la interfaz gráficay las llamadas al sistema; las llamadas son servidas con ayuda del Executive.

El Executive

No se debe confundir el Executive con el núcleo de Windows NT, aunque muchasveces se usan (incorrectamente) como sinónimos. El Executive consta de unaserie de componentes software, que se ejecutan en modo privilegiado, y uno delos cuales es el núcleo. Dichos componentes son totalmente independientes entresí, y se comunican a través de interfaces bien definidas. Recordemos que en eldiseño se procuró dejar el núcleo tan pequeño como fuera posible, y, comoveremos, la funcionalidad del núcleo es mínima. Pasemos a comentar cada módulo.

El Administrador de Objetos (Object Manager)

Se encarga de crear, destruir y gestionar todos los objetosdel Executive. Tenemos infinidad de objetos: procesos, subprocesos, ficheros,segmentos de memoria compartida, semáforos, mutex, sucesos, etc. Lossubsistemas de entorno (Win32, OS/2 y POSIX) también tienen sus propiosobjetos. Por ejemplo, un objeto ventana es creado (con ayuda del administradorde objetos) y gestionado por el subsistema Win32. La razón de no incluir lagestión de ese objeto en el Executive es que una ventana sólo es innata de lasaplicaciones Windows, y no de las aplicaciones UNIX o OS/2. Por tanto, elExecutive no se encarga de administrar los objetos relacionados con el entornode cada SO concreto, sino de los objetos comunes a los tres.

El Administrador de Procesos (Process Manager)

Se encarga (en colaboración con el administrador e objetos)de crear, destruir y gestionar los procesos y subprocesos. Una de sus funcioneses la de repartir el tiempo de CPU entre los distintos subprocesos (ver el capítulode los procesos). Suministra sólo las relaciones más básicas entre procesos ysubprocesos, dejando el resto de las interrelaciones entre ellos a cadasubsistema protegido concreto. Por ejemplo, en el entorno POSIX existe unarelación filial entre los procesos que no existe en Win32, de manera que seconstituye una jerarquía de procesos. Como esto sólo es específico de esesubsistema, el administrador de objetos no se entromete en ese trabajo y lo dejaen manos del subsistema.

El Administrador de Memoria Virtual (Virtual Memory Manager)

Windows NT y UNIX implementan un direccionamiento lineal de32 bits y memoria virtual paginada bajo demanda. El VMM se encarga de todo lorelacionado con la política de gestión de la memoria: determina los conjuntosde trabajo de cada proceso, mantiene un conjunto de páginas libres, elige páginasvíctima, sube y baja páginas entre la memoria RAM y el archivo de intercambioen disco, etc. Una explicación detallada la dejaremos para el capítulo de lamemoria.

Facilidad de Llamada a Procedimiento Local (LPC Facility)

Este módulo se encarga de recibir y envíar las llamadas aprocedimiento local entre las aplicaciones cliente y los subsistemas servidores.

Administrador de Entrada/Salida (I/O Manager)

Consiste en una serie de subcomponentes, que son:

El administrador del sistema de ficheros

El servidor y el redirector de red

Los drivers de dispositivo del sistema

El administrador de caches

Buena parte de su trabajo es la gestión de la comunicaciónentre los distintos drivers de dispositivo, para lo cual implementa una interfazbien definida que permite el tratamiento de todos los drivers de una manerahomogénea, sin que intervenga el cómo funciona específicamente cada uno.

Trabaja en conjunción con otros componentes del Executive,sobre todo con el VMM. Le proporciona la E/S síncrona y asíncrona, la E/S aarchivos asignados en memoria y las caches de los ficheros.

El administrador de caches no se limita a gestionar unoscuantos buffers de tamaño fijo para cada fichero abierto, sino que es capaz deestudiar las estadísticas sobre la carga del sistema y variar dinámicamenteesos tamaños de acuerdo con la carga. El VMM realiza algo parecido en sutrabajo, como veremos en su momento.

Este componente da soporte en modo privilegiado al subsistemade seguridad, con el que interacciona. Su misión es actuar de alguna maneracomo supervisor de accesos, ya que comprueba si un proceso determinado tienepermisos para acceder a un objeto determinado, y monitoriza sus acciones sobredicho objeto.

De esta manera es capaz de generar los mensajes de auditorías.Soporta las validaciones de acceso que realiza el subsistema de seguridad local.

En UNIX, de la seguridad se encargaba un módulo llamado elKerberos (Cancerbero), desarrollado por el MIT como parte del Proyecto Atenas.Kerberos se ha convertido en una norma de facto, y se incorporará a Windows NTen su versión 5.0.

El Núcleo (Kernel)

Situado en el corazón de Windows NT, se trata de unmicro-kernel que se encarga de las funciones más básicas de todo el SO:

Ejecución de subprocesos

Sincronización multiprocesador

Manejo de las interrupciones hardware

Nivel de Abstracción de Hardware (HAL)

Es una capa de software incluida en el Executive que sirve deinterfaz entre los distintos drivers de dispositivo y el resto del sistemaoperativo. Con HAL, los dispositivos se presentan al SO como un conjunto homogéneo,a través de un conjunto de funciones bien definidas. Estas funciones son llamadas tanto desde el SO como desde los propios drivers. Permite a los drivers de dispositivo adaptarse a distintas arquitecturas de E/S sin tener que sermodificados en gran medida. Además oculta los detalles hardware que conlleva el multiprocesamiento simétrico de los niveles superiores del SO.

Llamadas a Procedimientos Locales y Remotos

Windows NT, al tener una arquitectura cliente-servidor, implementa elmecanismo de llamada a procedimiento remoto (RPC) como medio de comunicaciónentre procesos clientes y servidores, situados ambos en máquinas distintas dela misma red. Para clientes y servidores dentro de la misma máquina, la RPC toma la forma de llamada a procedimiento local (LPC). Vamos a estudiar endetalle ambos mecanismos pues constituyen un aspecto fundamental del diseño deWindows NT.

RPC (Remote Procedure Call)

Se puede decir que el sueño de los diseñadores de Windows NT es que algúndía se convierta en un sistema distribuido puro, es decir, que cualquiera desus componentes pueda residir en máquinas distintas, siendo el kernel en cada máquina el coordinador general de mensajes entre los distintos componentes. En la última versión de Windows NT esto no es aún posible.

No obstante, el mecanismo de RPC permite a un proceso clienteacceder a una función situada en el espacio virtual de direcciones de otroproceso servidor situado en otra máquina de una manera totalmente transparente.

Vamos a explicar el proceso en conjunto. Supongamos que setiene un proceso cliente ejecutándose bajo una máquina A, y un proceso servidor bajo una máquina B. El cliente llama a una función f de una biblioteca determinada. El código de f en su biblioteca es una versión especial del código real; el código real reside en el espacio de direcciones del servidor. Esa versión especial de la función f que posee el cliente se denomina proxy. El código proxy lo único que hace es recoger los parámetros de la llamada a f, construye con ellos un mensaje, y pasa dicho mensaje al Executive. El Executive analiza el mensaje, determina que va destinado a la máquina B, y se lo envía a través del interfaz de transporte. El Executive de la máquina B recibe el mensaje, determina a qué servidor va dirigido, y llama a un código especial de dicho servidor, denominado stub, al cual le pasa el mensaje. El stub desempaqueta el mensaje y llama a la función f con los parámetros adecuados, ya en el contexto del proceso servidor. Cuando f retorna, devuelve el control alcódigo stub, que empaqueta todos los parámetros de salida (si los hay), forma así un mensaje y se lo pasa al Executive.

Ahora se repite el proceso inverso; el Executive de B envíael mensaje al Executive de A, y este reenvía el mensaje al proxy. El proxyd esempaqueta el mensaje y devuelve al cliente los parámetros de retorno de f.Por tanto, para el cliente todo el mecanismo ha sido transparente. Ha hecho unallamada a f, y ha obtenido unos resultados; ni siquiera tiene que saber si el código real de f está en su biblioteca o se encuentra en una máquina situada tres plantas más abajo.

LPC (Local Procedure Call)

Las LPC se pueden considerar una versión descafeinada de lasRPC. Se usan cuando un proceso necesita los servicios de algún subsistemaprotegido, típicamente Win32. Se intentara descubrir su funcionamiento.

El proceso cliente tiene un espacio virtual de 4 Gb. Los 2 Gbinferiores son para su uso (excepto 128 Kb). Los 2 Gb superiores son para usodel sistema.

Vamos a suponer que el cliente realiza una llamada a la funciónCreateWindow. Dicha función crea un objeto ventana y devuelve un descriptor al mismo. No es gestionada directamente por el Executive, sino por el subsistema Win32 (con algo de colaboración por parte del Executive, por supuesto; por ejemplo, para crear el objeto). El subsistema Win32 va guardando en su propioespacio de direcciones una lista con todos los objetos ventana que le vanpidiendo los procesos. Por consiguiente, los procesos no tienen acceso a la memoria donde están los objetos; simplemente obtienen un descriptor para trabajar con ellos. Cuando el cliente llama a CreateWindow, se salta al código de esa función que reside en la biblioteca USER32.DLL asignada en el espacio de direcciones del cliente.

Por supuesto, ese no es el código real, sino el proxy. Elproxy empaqueta los parámetros de la llamada, los coloca en una zona de memoria compartida entre el cliente y Win32, pone al cliente a dormir y ejecuta una LPC. La facilidad de llamada a procedimiento local del Executive captura esa llamada, y en el subsistema Win32 se crea un subproceso que va a atender a la peticióndel cliente. Ese subproceso es entonces despertado, y comienza a ejecutar el correspondiente código de stub. Los códigos de stub de los subsistemas seencuentran en los 2 Gb superiores (los reservados) del espacio virtual delproceso cliente. Aunque no he encontrado más documentación al respecto, es muyprobable que dichos 2 Gb sean los mismos que se ven desde el espacio virtual deWin32. Sea como sea, el caso es que el stub correspondiente desempaqueta los parámetrosdel área de memoria compartida y se los pasa a la función CreateWindow situadaen el espacio de Win32. Ése sí es el código real de la función. Cuando la función retorna, el stub continúa, coloca el descriptor a la ventana en la memoria compartida, y devuelve el control de la LPC al Executive. El subproceso del Win32 es puesto a dormir. El Executive despierta al subproceso cliente, queestaba ejecutando código proxy. El resto de ese código lo que hace es simplemente tomar el descriptor y devolverlo como resultado de la función CreateWindow.

 

4. Procesos

Definición de Proceso y Sub Proceso

Debemos tener cuidado con no confundir el proceso en Windows NT con elproceso en los SO más clásicos, como UNIX. Vamos a intentar dar una definicióngeneral de lo que entiende Windows NT por proceso y subproceso, aunque despuésiremos perfilando poco a poco ambos conceptos.

Un proceso es una entidad no ejecutable que posee un espaciode direcciones propio y aislado, una serie de recursos y una serie desubprocesos. En el espacio de direcciones hay colocado algún código ejecutable(entre otras cosas). Bien, hemos dicho que un proceso es una entidad"no-ejecutable". En efecto, no puede ejecutar el código de su propioespacio de direcciones, sino que para esto le hace falta al menos un subproceso.Por consiguiente, un subproceso es la unidad de ejecución de código. Unsubproceso está asociado con una serie de instrucciones, unos registros, unapila y una cola de entrada de mensajes (enviados por otros procesos o por elSO).

Cuando se crea un proceso, automáticamente se crea unsubproceso asociado (llamado subproceso primario). Los subprocesos también sellaman "hebras de ejecución" (threads of execution). Debe quedarnosmuy claro, pues, que lo que se ejecutan son subprocesos, no procesos. Losprocesos son como el soporte sobre el que corren los subprocesos. Y entre lossubprocesos se reparte el tiempo de CPU.

Podemos pensar en los subprocesos de Windows NT como losprocesos de los SO clásicos (aunque existen matices, como sabemos). A veces,por comodidad y por costumbre, usaremos ambos términos como sinónimos, ydiremos que "el proceso A llama a CreateWindow", aunque se debeentender que "un subproceso del proceso A llama a CreateWindow".

Un proceso tiene un espacio de direcciones virtuales de 4 Gb.En algún lugar de ese espacio se halla un código ejecutable (que quizás es laimagen de un programa en disco). Un proceso puede crear subprocesos, estando sunúmero fijado por el sistema. Se dice que muere cuando todos sus subprocesoshan muerto (incluso aunque el subproceso primario haya muerto, si aún existealgún subproceso propiedad del proceso, el proceso seguirá vivo).

Planificación del Tiempo de la CPU por Round Robin conPrioridades

Windows NT utiliza la planificación del anillo circular o round robin. Estatécnica consiste en que los subprocesos que pueden ser ejecutados se organizanformando un anillo, y la CPU va dedicándose a cada uno durante un tiempo. Eltiempo máximo que la CPU va a estar dedicada a cada uno se denomina quantum, yes fijado por el Administrador del Sistema.

Si el subproceso está esperando por alguna entrada-salida opor algún suceso, la CPU lo pondrá a dormir, y pondrá en ejecución alsiguiente del anillo. Si un subproceso que la CPU está ejecutando consume suquantum, la CPU también lo pondrá a dormir, pasando al siguiente.

En Windows NT, existe un rango de prioridades que va del 1 al31, siendo 31 la más alta. Todo proceso y subproceso tienen un valor deprioridad asociado.

Existe un anillo o cola circular por cada uno de los nivelesde prioridad. En cada anillo están los subprocesos de la misma prioridad. ElExecutive comienza a repartir el tiempo de CPU en el primer anillo de mayorprioridad no vacío. A cada uno de esos subprocesos se les asignasecuencialmente la CPU durante el tiempo de un quantum, como ya indicamos antes.Cuando todos los subprocesos de nivel de prioridad n están dormidos, elExecutive comienza a ejecutar los del nivel (n-1), siguiendo el mismo mecanismo.

Análogamente, si un subproceso se está ejecutando, yllegara uno nuevo de prioridad superior, el Executive suspendería al primero(aunque no haya agotado su quantum), y comenzaría a ejecutar el segundo (asignándoleun quantum completo).

Prioridad de proceso y subproceso

Un proceso se dice que pertenece a una clase de prioridad.Existen cuatro clases de prioridad, que son:

Desocupado. Corresponde a un valor de prioridad 4.

Normal. Corresponde a un valor de prioridad 7 ó 9.

Alta. Corresponde a un valor de prioridad 13.

Tiempo Real. Corresponde a un valor de prioridad 24.

La clase "Normal" es la que el Executive asocia alos procesos por defecto. Los procesos en esta clase se dice que tienen unaprioridad dinámica: el Executive les asigna un valor de 7 si se estánejecutando en segundo plano, mientras que si pasan a primer plano, la prioridadse les aumenta a un valor de 9.

La clase "Desocupado" va bien para procesos que seejecuten periódicamente y que por ejemplo realicen alguna función demonitorización.

La clase "Alta" la tienen procesos tales como elAdministrador de Tareas (Task Manager). Dicho proceso está la mayor parte deltiempo durmiendo, y sólo se activa si el usuario pulsa Control-Esc. Entonces,el SO inmediatamente pone a dormir al subproceso en ejecución (aunque no hayaagotado su quantum) y ejecuta al subproceso correspondiente del procesoAdministrador de Tareas, que visualizará el cuadro de diálogo característico,mostrándonos las tareas actuales.

La clase "Tiempo Real" no es recomendable que latenga ningún proceso normal. Es una prioridad más alta incluso que muchosprocesos del sistema, como los que controlan el ratón, el teclado, elalmacenamiento en disco en segundo plano, etc. Es evidente que usar estaprioridad sin un control extremo puede causar consecuencias nefastas.

Así como un proceso tiene una prioridad oscilando entrecuatro clases, un subproceso puede tener cualquier valor en el rango [1,31]. Enprincipio, cuando el subproceso es creado, su prioridad es la correspondiente ala de la clase de su proceso padre. Pero este valor puede ser modificado si elsubproceso llama a la función

BOOL SetThreadPriority (HANDLE hThread, int nPriority);

Donde:

hThread es el descriptor del subproceso

nPriority puede ser:

THREAD_PRIORITY_LOWEST : resta 2 a la prioridad del padre

THREAD_PRIORITY_BELOW_NORMAL: resta 1 a la prioridad delpadre

THREAD_PRIORITY_NORMAL: mantiene la prioridad del padre

THREAD_PRIORITY_ABOVE_NORMAL: suma 1 a la prioridad del padre

THREAD_PRIORITY_HIGHEST: suma 2 a la prioridad del padre

THREAD_PRIORITY_IDLE: hace la prioridad igual a 1,independientemente de la prioridad del padre

THREAD_PRIORITY_TIME_CRITICAL: hace la prioridad igual a 15si la clase de prioridad del padre es desocupada, normal o alta; si es tiemporeal, entonces hace la prioridad igual a 31

De esta manera es como calcula el Executive la prioridad deun subproceso. Por tanto, la prioridad de un subproceso es relativa a la de supadre (excepto en IDLE y TIME_CRITICAL). Mediante suma y resta de la prioridaddel padre obtenemos todo el rango de prioridades:

Clase proceso padre

Prior. Subproceso

Clase desocupado

Clase normal en primer plano

Clase normal en segundo plano

Clase alta

Clase tiempo real

Crítico en tiempo

15,00

15,00

15,00

15,00

31,00

Más alta

6,00

9,00

11,00

15,00

26,00

Más que normal

5,00

8,00

10,00

14,00

25,00

Normal

4,00

7,00

9,00

13,00

24,00

Menos que normal

3,00

6,00

8,00

12,00

23,00

Más baja

2,00

5,00

7,00

11,00

22,00

Desocupado

1,00

1,00

1,00

1,00

16,00

 

La ventaja de este sistema de las prioridades relativas esque si un proceso cambia su clase de prioridad durante su vida, sus subprocesoshijos tendrían sus prioridades automáticamente actualizadas.

Creación y destrucción de procesos

La llamada al sistema que crea un proceso es una de las máscomplejas de todo el API Win32. Vamos a comentarla para comprender mejor laforma en la que el Executive trabaja.

Un proceso se crea cuando un subproceso de otro proceso haceuna llamada a:

BOOL CreateProcess (LPCTSTR lpszImageName, LPCTSTR lpszCommandLine,LPSECURITY_ATTRIBUTES lpsaProcess, LPSECURITY_ATTRIBUTES lpsaThread, BOOLfInheritHandles, DWORD fdwCreate, LPVOID lpvEnvironment, LPTSTR lpszCurDir,LPSTARTUPINFO lpsiStartInfo, LPROCESS_INFORMATION lppiProcInfo);

El Executive crea un espacio virtual de 4 Gb para el proceso,y también crea el subproceso primario. Veamos el significado de los parámetros:

lpszImageName: es el nombre del archivo que contiene el códigoejecutable que el Executive asignará en el espacio virtual del proceso. Si esNULL, entonces se entenderá que viene dado en el siguiente parámetro.

lpszCommandLine: argumentos para el nombre del archivo

lpsaProcess, lpsaThread y fInheritHandles: los dos primerosson punteros con los que podemos dar unos atributos de seguridad para el procesoy su subproceso primario. Si pasamos NULL, el sistema pondrá los valores pordefecto. Los parámetros son punteros a una estructura del tipo:

El campo lpSecurityDescriptor se refiere a permisos sobre elobjeto proceso, pero no he encontrado más información al respecto.

De esta estructura vamos a destacar el campo bInheritHandle,que se refiere a la herencia. En Windows NT, cualquier objeto que creemos va atener asociada una estructura de este tipo en donde se indicará, con el parámetrobInheritHandle, si dicho objeto es heredable o no. El objeto es propiedad de unproceso. Ese proceso puede crear procesos hijos; dichos procesos, por defecto,no heredarán ninguno de los objetos de su padre. Los procesos hijos que tenganla capacidad de heredar, heredarán aquellos objetos de su padre que tengan elcampo bInheritHandle a TRUE.

Ahora bien, un proceso y un subproceso son también objetos.Por tanto, ambos objetos podrán ser heredables por otros procesos. Si el campobInheritHandle es TRUE en la estructura apuntada por lpsaProcess, entonces elproceso que estamos creando será heredable por otros procesos hijos de su mismopadre.

Si el campo bInheritHandle es TRUE en la estructura apuntadapor lpsaThread, entonces e subproceso primario del proceso que estamos creandoserá igualmente heredable.

Resta explicar el parámetro fInheritHandles. Si vale TRUE,entonces el proceso que estamos creando podrá heredar todos los objetosheredables de su padre (es decir, aquellos objetos cuyo campo bInheritHandle seaTRUE).

No se debe confundir todo esto con herencia entre procesos y subprocesoshijos. Un subproceso siempre podrá tener acceso a los objetos creados por elproceso al que pertenece (o mejor dicho, creados por algún otro subproceso delproceso al que pertenece).

fdwCreate: es una máscara donde se pueden especificar (mediante OR lógica)muchos indicadores para el proceso a crear. Los más importantes son:la clase deprioridad del proceso: IDLE_PRIORITY_CLASS (desocupado), NORMAL_PRIORITY_CLASS(normal), HIGH_PRIORITY_CLASS (alta), REALTIME_PRIORITY_CLASS (tiempo real)si elproceso va a ser dormido al crearse, usando CREATE_SUSPENDED

lpvEnvironment: apunta a un bloque de memoria que contienecadenas de entorno. Si vale NULL, usará las mismas cadenas que su procesopadre. Las cadenas de entorno no son más que variables con algún valor queusarán los procesos con algún fin, (por ejemplo, el directorio home, el path).Tiene un significado similar al concepto de entorno de UNIX.

lpszCurDir: cadena con directorio y unidad de trabajo para elnuevo proceso.

lpsiStartInfo: apunta a una estructura bastante grande que novamos a escribir. Los campos de dicha estructura dan informaciones al subsistemaWin32 como por ejemplo si el proceso va a estar basado en GUI o en consola (GUIes con ventanas; consola es simulando el modo texto), el tamaño de la ventanainicial del proceso, las coordenadas de dicha ventana, su tamaño, su título...

En hprocess y hThread el Executive devuelve un par dedescriptores a los objetos proceso y subproceso primario recién creados, y queservirán para hacer referencias a los mismos. Cada vez que el Executive creacualquier objeto, asocia con dicho objeto un contador de uso. Cada vez que unproceso distinto usa un mismo objeto, incrementa el contador en 1. Cada vez queun proceso libera un objeto, decrementa el contador en 1. Cuando el contador deuso de un objeto es 0, el Executive destruye el objeto. Pues bien, cuandoCreateProcess devuelve el control, los objetos proceso y subproceso primariotienen sus respectivos contadores con valor 2. De este modo, para que elExecutive pueda destruirlos, habrán de ser liberados dos veces: una, cuandoellos mismos terminen (el contador pasaría a valer 1), y otra, cuando elproceso padre los libere (o sea, cuando cierre los descriptores; así, suscontadores valdrían 0 y 0, y el Executive los destruiría). De aquí es infiereque es vital que el proceso padre cierre esos descriptores (si no, no sedestruirían los objetos y podría desbordarse la memoria). La llamada paracerrar descriptores es

BOOL CloseHandle (HANDLE hobject);

dwProcessId y dwThreadId son unos identificadores únicos queel Executive asocia al proceso y subproceso primario, respectivamente, análogosal PID en UNIX.

Hasta aquí la llamada al sistema que nos permite crearprocesos. La llamada para finalizar el proceso es, afortunadamente, mucho mássimple:

VOID ExitProcess (UINT fuExitCode); que devuelve el enterofuExitCode, que es un código de salida que el proceso envía antes de finalizar(que diga si ha finalizado con éxito, si no, etc). Cuando un proceso termina,se realizan las siguientes acciones:

Todos los subprocesos del proceso finalizan

Se cierran todos los descriptores de objetos del Executive yde Win32 abiertos por el proceso

El estado del objeto proceso para a estar señalado

El estado de terminación del proceso se pone al código desalida adecuado

Hemos dicho que el objeto proceso se pone a estado señalado. Un objeto puedetener dos estados: señalado y no señalado, estados que utiliza el sistema ylos propios procesos para varias funciones. El curioso lector puede consultar elapartado de "Comunicación entre procesos".

Creación y destrucción de subprocesos

Análogamente a como nos hemos auxiliado de la llamada alsistema CreateProcess para comprender el mecanismo de creación de procesos,vamos a hacer lo propio para la creación de subprocesos. Un subproceso se creacuando otro subproceso hace una llamada a:

HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpsa, DWORD cbStack,LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParm, DWORD fdwCreate,LPDWORD lpIDThread);

lpsa: tiene el mismo significado que en CreateProcess, es decir, un puntero auna estructura SECURITY_ATTRIBUTES, donde se especifican permisos del subprocesoy si es heredable o no.

cbStack: vamos a aprovechar este parámetro para explicar la pila de unsubproceso. Todo subproceso tiene una pila asociada situada en el espaciovirtual del proceso al que pertenece. Virtualmente, la pila tiene un tamaño pordefecto de 1 Mb (y además es el máximo; tamaños inferiores pueden serindicados al enlazar la aplicación). De esa pila virtual el subproceso puedetener asignada en memoria un trocito. El tamaño de ese trocito viene dado porel parámetro cbStack, y por defecto es 1 página (4 Kb). Técnicamente, se diceque la pila tiene reservado un espacio de 1 Mb, y asignado un espacio de cbStackbytes. (el significado de ambos términos lo veremos detenidamente en el capítulode administración de la memoria). Si el subproceso desborda su trocito de pilaasignado en memoria se eleva una excepción; el Executive captura la excepcióny asigna otros cbStack bytes en memoria física para la pila del subproceso. Portanto, la pila crece dinámicamente en trozos de cbStack bytes. Lo máseficiente es que cbStack sea múltiplo del tamaño de la página.

lpStartAddr, lpThreadParm: ya dijimos que todo subprocesoejecuta una porción de código del proceso al que pertenece. Este parámetroapunta a la función que contiene el código a ejecutar por nuestro subproceso.Es posible hacer que varios subprocesos tengan la misma función asociada. Elperfil de la función es fijo:

El parámetro lpvThreadParm de la función es justamente elmismo que se le pasa a CreateThread; de hecho, el sistema se limita a pasardicho parámetro a la función asociada al subproceso cuándo éste comienza suejecución.

El parámetro puede ser un valor de 32 bits o un puntero de32 bits. Puede servir para dar algún tipo de inicialización al subproceso.

El parámetro dwresult de la anterior función es un códigode salida que el subproceso devuelve cuando acaba de ejecutar código. Essimilar al código que devuelven los procesos al acabar.

fdwCreate: si vale 0, entonces el subproceso comienza aejecutarse en cuanto esté creado. Si vale CREATE_SUSPENDED, entonces se creará,pero automáticamente será suspendido.

lpIDThread: debe ser un puntero a una estructura DWORD, dondeel Executive pondrá el identificador que le ha asignado al subproceso. Esobligatorio pasar una dirección válida.

El subproceso recién creado iniciará su ejecucióninmediatamente antes del retorno de CreateThread (a menos que hayamosespecificado el indicador CREATE_SUSPENDED).

Comunicación y Sincronización de Procesos Mediante Objetos

En Windows NT, los mecanismos clásicos de sincronización entre procesos(como los semáforos, las regiones críticas, los sucesos, etc.) son tratadoscomo objetos. Es más, existen objetos no específicos de sincronización peroque también pueden ser usados con estos fines. Por tanto, vamos en primer lugara enumerar todos los objetos de sincronización y a dar algunas característicasglobales, para posteriormente adentrarnos a estudiar los más importantes.

Podemos sincronizar subprocesos mediante alguno de lossiguientes objetos:

    • Semáforos
    • Mutexes
    • Sucesos
    • Archivos
    • Procesos
    • Subprocesos
    • Entrada del terminal
    • Notificación de cambio de archivo

       

Antes hemos mencionado las regiones críticas. Aunque WindowsNT las incluye como mecanismo de sincronización, no las trata explícitamentecomo objeto. No obstante también las estudiaremos en este apartado por mantenerla homogeneidad.

Como ya esbozamos en el capítulo de los procesos, en cualquier instante unobjeto está en uno de dos estados: señalado (1) y no señalado (0). Cadaestado tiene un significado dependiendo de la clase del objeto.

Por ejemplo, en el apartado anterior vimos que durante la vida de un procesoo un subproceso su estado era no señalado, pero que al morir pasaban al estadoseñalado. De aquí que ambos tipos de objetos sirvan para la sincronización.Por ejemplo, un subproceso A puede querer dormir hasta que otroproceso/subproceso B acabe; por tanto, A dormirá mientras el objeto asociado alB esté no señalado. En cuanto B pase a señalado, A despertará.

Igualmente, un subproceso se puede sincronizar con el fin de unalectura/escritura en un archivo. En general, cuando alguna de estas operacionesfinalizan, el objeto archivo en cuestión pasa a estado señalado.

El objeto asociado a la entrada de teclado se pone señalado cuando existealgo en el buffer de entrada. La aplicación de este hecho para sincronizaciónes evidente. Un subproceso puede así estar durmiendo mientras el buffer estévacío.

El resto de objetos los veremos con más detalle a lo largo de este capítulo.Pero antes vamos a dar las llamadas al sistema que se utilizan para lasincronización con objetos.

Se trata de:

DWORD WaitForSingleObject (HANDLE hObject, DWORD dwTimeout);

Esta llamada simplemente mantiene al subproceso que larealiza dormido hasta que el objeto identificado por hObject pase al estado señalado.El parámetro dwTimeout indica el tiempo (en ms) que el subproceso quiereesperar por el objeto. Si vale 0, entonces la llamada sólo hace una comprobacióndel estado y retorna inmediatamente; si devuelve WAIT_OBJECT_0, el objeto estabaseñalado; si devuelve WAIT_TIMEOUT, el objeto estaba no señalado. Si comotiempo metemos INFINITE, el subproceso dormirá hasta que el objeto pase a señalado.Hay un par de códigos de salida más que comentaremos en su momento (cuandoexpliquemos los mutex).

DWORD WaitForMultipleObjects (DWORD cObjects, LPHANDLElpHandles, BOOL bWaitAll, DWORD dwTimeout);

Es parecida a la anterior pero da la posibilidad de esperarpor varios objetos o bien por alguno de una lista de objetos. cObjects indica elnúmero de objetos a comprobar. lpHandles apunta a una matriz que contienedescriptores a los objetos. El booleano bWaitAll indica si queremos esperar aque todos los objetos pasen a estado señalado o tan sólo uno, y dwTimeout esel tiempo a esperar. Si hay varios objetos que han pasado al estado señalado,la llamada coge sus descriptores, toma el menor y devuelve su posición dentrode la matriz (sumada a un código de retorno análogo a los deWaitForSingleObject).

El tema de sincronización está íntimamente relacionado conel de interbloqueos. Supongamos que tenemos dos subprocesos A y B compitiendopor dos objetos 1 y 2, esperando a que ambos estén señalados, para lo cual hanhecho sendas llamadas a WaitForMultipleObjects. Supongamos que 1 pasa a estadoseñalado. Y supongamos que el Executive decidiera otorgar ese hecho al procesoA, colocando a 1 de nuevo a no señalado. Mientras tanto, 2 pasa también a señalado,y el Executive otorga este hecho a B, y también pone a 2 a no señalado. Enesta situación, ninguno de los dos subprocesos podría terminar nunca, puescada uno estaría esperando a que el objeto del otro pasara a señalado.Entonces A y B están interbloqueados. Para evitar esta situación, el Executiveno entrega los objetos hasta que ambos estén señalados; en ese momentodespertaría a uno de los subprocesos. El otro seguiría dormido hasta que elprimer subproceso terminara de trabajar con los objetos.

A continuación se estudia cada uno de los objetos específicosde sincronización de Windows NT.

Secciones Críticas

Las secciones críticas son un mecanismo para sincronizarsubprocesos pertenecientes a un mismo proceso, pero, como ya hemos indicado, noson objetos.

Una sección o región crítica (SC) es un trozo de códigoejecutable tal que para que un subproceso pueda ejecutarlo se requiere que tengaacceso a una estructura de datos especial y compartida.

Dicha estructura es del tipo CRITICAL_SECTION, cuyos camposno son interesantes, y además no son accesibles directamente, sino a través deuna llamada al subsistema Win32:

VOID InitializeCriticalSection (LPCRITICAL_SECTIONlpCriticalSection);

Veamos algunas llamadas para manejar las SC:

VOID EnterCriticalSection (LPCRITICAL_SECTION lpCriticalSection);

VOID LeaveCriticalSection (LPCRITICAL_SECTION lpCriticalSection);

La primera sirve para que un subproceso solicite entrar en una SC. La segundapermite salir de la SC a un subproceso que esté dentro de la misma.

La función de entrar opera así: la primera vez que es llamada, se registraen la estructura CRITICAL_SECTION un identificador del subproceso que la posee.

Si antes de que el subproceso la abandone, el SO entrega la CPU a otro (elcaso más frecuente), y entonces ese otro subproceso hace la llamada para entraren la SC, entonces la función ve que la estructura ya está en uso, con lo queel segundo subproceso sería puesto a dormir.

Cuando la CPU vuelva al primero y éste haga una llamada parasalir, la estructura será asignada al segundo subproceso.

Si un subproceso vuelve a llamar a la función de entrarestando ya dentro de la SC, simplemente se incrementará un contador de usoasociado con el objeto SC. Más tarde, deberá hacer tantas otras llamadas a lafunción de salir para poner el contador a 0; en caso contrario, ningún otrosubproceso podría ocupar la SC.

La estructura CRITICAL_SECTION y todos los recursos que el SOle hubiera asignado se pueden eliminar haciendo una llamada a

VOID DeleteCriticalSection (LPCRITICAL_SECTIONlpCriticalSection);

Sería catastrófico usar esta función estando un subprocesodentro.

Exclusión Mutua (Mutex)

Los objetos exclusión mutua (abreviadamente mutex, de mutualexclusión) son muy parecidos a las SC, pero permiten sincronizar subprocesospertenecientes a procesos distintos.

Se crean con la llamada:

HANDLE CreateMutex (LPSECURITY_ATTRIBUTES lpsa, BOOLfInitialOwner, LPTSRT lpszMutexName);

fInitialOwner: dice si el subproceso que crea el mutex ha deser su propietario inicial o no. Si vale TRUE, entonces el estado inicial delobjeto mutex sería no señalado, por lo que todo subproceso que espere por élsería inmediatamente puesto a dormir. Si vale FALSE, el mutex se crea conestado señalado, por lo que al primer proceso que estuviera esperando le seríaasignado y podría continuar ejecutándose.

lpszMutexName: apunta a una cadena con el nombre que le hemosquerido dar al objeto (o NULL si no se pone un nombre).

La llamada devuelve un descriptor al objeto creado.

Si otro subproceso llamara a la función pasándole el mismonombre de mutex, el SO comprobaría que ya está creado y devolvería otrodescriptor al mismo objeto.

HANDLE OpenMutex (DWORD fwdAccess, BOOL fInherit, LPTSTRlpszMutexName);

Esta función comprobaría si existe algún objeto mutex connombre lpszMutexName. Si es así, devolvería un descriptor al mismo. Si no,devolvería NULL. El booleano fInherit permite que el mutex sea heredado por lossubprocesos hijos.

Si el mutex no tuviera nombre, un subproceso podría obtenerun descriptor al mismo llamando a DuplicateHandle.

Otra diferencia de los mutex con las SC (y en general concualquier objeto de sincronización en Windows NT) es que un subproceso mantienela propiedad de un mutex hasta que quiera liberarlo, pero hasta el punto de que,si el subproceso muere y no ha liberado al mutex, éste seguiría siendo de supropiedad.

Así, si un mutex está libre (señalado) y es tomado por unsubproceso (pasa a no señalado), y dicho subproceso finaliza antes deliberarlo, el estado del mutex pasaría a señalado; los subprocesos queestuvieran esperando por el mutex serían despertados pero no se les asignaríael objeto a ninguno, sino que con el valor WAIT_ABANDONED de retorno de lasllamadas WaitFor...Object(s) se les informaría de lo que ha sucedido, de que elmutex no ha sido liberado sino abandonado. Esto se considera como una situaciónde fallo en un programa.

Para liberar un mutex usaremos la llamada

BOOL ReleaseMutex (HANDLE hMutex);

Donde:

hMutex: es un descriptor al objeto. La función decrementa elcontador de uso que el subproceso tiene sobre el mutex. Cuando sea 0, el objetopodrá ser asignado al primer subproceso que por él esté esperando, igual quecon las SC.

Semáforos

Un semáforo es un objeto distinto de las SC y los mutex. Adiferencia de ambos, el objeto semáforo puede ser poseído a la vez por variossubprocesos, y no posee dentro ningún identificador del subproceso/s que lo estáusando. Lo que tiene es un contador de recursos, que indica el número desubprocesos que pueden acceder al semáforo. Cuando un subproceso toma el objetosemáforo, el SO mira si el contador de recursos del mismo es 0. De ser así,pone al subproceso a dormir. Si no es 0, asigna el semáforo al subproceso ydecrementa el contador. Cada vez que un subproceso libera el semáforo, seincrementa el contador.

Un semáforo está señalado cuando su contador es mayor que0, y no señalado cuando su contador vale 0.

Un semáforo se crea con la llamada:

HANDLE CreateSemaphore (LPSECURITY_ATTIBUTES lpsa, LONG cSemInitial, LONGcSemMax, LPTSTR lpszSemName);

cSemInitial es el valor inicial no negativo del contador de recursos.

cSemMax es el valor máximo que puede alcanzar dicho contador (por tanto 0<= cSemInitial <= cSemMax)

lpszSemName es el nombre que le damos al objeto.

HANDLE OpenSemaphore (DWORD fdwAccess, BOOL fInherit, LPTSTR lpszName);

La semántica de esta llamada es análoga a la de OpenMutex.

Para incrementar el contador de referencia del semáforo se usa:

HANDLE ReleaseSemaphore (HANDLE hSemaphore, LONG cRelease, LPLONGlplPrevious);

Donde:

cRelease indica el número de veces que queremos incrementar el contador (elnúmero de veces que liberamos el semáforo). A la vuelta de la función,tendremos en lplPrevious un puntero al valor anterior del contador. Por tanto,si queremos averiguar el valor del contador tenemos que modificarlo. Ni siquierallamando a la función con cRelease igual a 0 podríamos saber el valor anteriorsin modificar el semáforo, pues entonces la función devuelve 0 como datoapuntado por lplPrevious.

Sucesos.

Los sucesos son objetos utilizados para indicar a lossubprocesos que ha ocurrido algo en el entorno. Se puede distinguir dos tipos deobjetos suceso:

Sucesos con inicialización manual.

Sucesos con autoinicialización.

Cualquier objeto suceso podrá estar en estado señalado o noseñalado. No señalado significa que la situación asociada con el objeto aúnno ha ocurrido. Señalado indica que sí se ha producido.

Ambos tipos de objeto se crean con la misma llamada:

HANDLE CreateEvent (LPSECURITY_ATTIBUTES lpsa, VOOLfManualReset, BOOL fInitialState, LPTSTR lpszEventName);

fManualReset a TRUE le indicará al SO que queremos crear unsuceso de inicialización manual, y a FALSE, un suceso de autoinicialización.

fInitialState indica el estado inicial del objeto; un valorTRUE significa que el suceso se creará como obejto señalado, y a FALSE como noseñalado.

Como vimos con los otros tipos de objetos de sincronización,otros procesos pueden acceder al mismo objeto usando CreateEvent y el mismonombre, o usando la herencia, o con DuplicateHandle, o con:

HANDLE OpenEvent (DWORD fdwAccess, BOOL fInherit, LPTSTRlpszName);

Sucesos con inicialización manual (manual reset)

Este tipo de objetos se usan para que, cuando el suceso ocurra, es decir, seponga a señalado, todos los subprocesos que esperaban por ese suceso sedespierten a la vez y todos puedan seguir ejecutándose. Por tanto, ahora lasfunciones WaitFor...Objext(s) no van a tocar el estado del objeto, sino que debehacerlo el propio subproceso que creó el objeto. Dicho subproceso puede usarlas llamadas:

BOOL SetEvent (HANDLE hEvent);

BOOL ResetEvent (HANDLE hEvent);

que ponen, respectivamente, el suceso identificado por hEvent en estado señaladoy no señalado. O sea, con SetEvent indicaremos que la situación asociada alobejto se ha producido, y con ResetEvent indicaremos lo contrario.

Existe una llamada muy útil con este tipo de objetos:

BOOL PulseEvent (HANDLE hEvent);

que le da un "pulso" al suceso hEvent: lo pone enestado señalado, con lo que se libera a todos los subprocesos en espera (que seseguirán ejecutando), y entonces lo pone a no señalado, con lo que lossubprocesos que a partir de ese momento esperen por el suceso serán dormidos.Por tanto, equivale a SetEvent + liberación + ResetEvent.

Sucesos con autoinicialización (auto-reset)

Con estos objetos las funciones WaitFor...Object(s) van afuncionar como con cualquier otro tipo de objeto. Por tanto, cuando la situaciónasociada con el suceso ocurra y éste se ponga a señalado (con SetEvent), sólouno de los subprocesos que estaban esperando podrá continuar, y su funciónWaitFor...Object(s) correspondiente pondrá el estado del objeto a no señalado.La función ResetEvent no tendría efecto aquí. La función PulseEvent pondríael suceso a señalado, liberaría un sólo subproceso de los que estánesperando, y pondría el suceso a no señalado.

 

5. Administracion De La Memoria

La parte de Windows NT que soporta la gestión de la memoriase denomina Gestor de Máquina Virtual (VMM), y reside en el Executive, porencima del núcleo pero ejecutándose en modo supervisor, como vimos en laintroducción.

En Windows NT se utiliza memoria virtual paginada. En algunas máquinas, comolas CPU Intel 386 en adelante, combina paginación con segmentación. El tamañode la página depende de la máquina. En la CPU anterior es de 4 Kb.

Espacio de Direcciones de un Proceso

Todo proceso que se crea en Windows NT posee un espacio de direccionesvirtuales de 4 Gb exclusivos de él. Ningún otro podrá acceder a esasdirecciones, sencillamente porque ¡no las ve!. Para un proceso, todo lo que vees suyo, y ve virtualmente 4 Gb. Los 2 Gb superiores están reservados al SO, asícomo los 64 Kb primeros y los 64 Kb últimos de los 2 Gb inferiores. El resto delos 2 Gb inferiores son para uso del proceso. Distinguimos varias zonas:

Direcciones para las DLL del sistema (NTDLL, KERNEL32, USER32, GDI32 ...).

Direcciones para las DLL propias de la aplicación.

Bloques y pilas de los subprocesos.

Imagen del archivo ejecutable: código, datos, cabecera, información deldepurador y tabla de activación imagen.

Además, cada proceso posee su propia tabla de implantación de páginas(TIP), a dos niveles. El objetivo de esa tabla (también llamada tabla detraducción) es, dada una dirección virtual, devolver su dirección físicaasociada. A veces la dirección virtual no tiene correspondencia en memoria física.Entonces se dice que se ha producido un fallo o defecto de página (page fault).En el siguiente apartado vamos a describir cómo funciona el VMM y qué hacecuando se dan los fallos de página.

Funcionamiento del VMM

Cada proceso tiene asignado un número que indica el máximo de páginas físicasque se le pueden conceder. Dicho número es ajustado por el llamado gestor delconjunto de trabajo, del que luego hablaremos. Además, cada proceso llevaasociada una lista que contiene referencias a las páginas físicas a las que seha accedido menos últimamente.

Cuando el proceso accede a una dirección que no tiene dirección físicaasociada en la TIP, se produce un fallo de página. Entonces, el VMM consulta elnúmero de páginas que el proceso tiene asignadas. Si no ha llegado al límite,se le concede una nueva página física y se escribe con la correspondientedesde el disco. Esto se denomina paginación bajo demanda. Si por el contrarioya había llegado al límite, entonces hay que descargar una página física aldisco para subir a memoria la que ocasionó el fallo. El VMM elige la página víctimade la lista de menos recientemente usadas del proceso.

Nótese que aunque existan páginas libres en la memoria, si el proceso agotasu número de páginas asignadas, se producirá el swapping, y además de una desus propias páginas. Este mecanismo puede parecer ilógico, pero presenta tantoventajas como inconvenientes. Como problema puede nombrar por ejemplo, que si unproceso estuviera gran parte del tiempo dormido (en espera de un suceso o de unaE/S), dicho proceso estaría ocupando páginas físicas que de otro modo podríanser descargadas. Como ventaja tenemos que, con este esquema, procesos querequieran muchos recursos no dejarán fuera de juego a aquellos cuya demanda dememoria sea escasa. No obstante, el problema planteado es paliado (al menos engran medida) por una parte del VMM llamada gestor del conjunto de trabajo.Realiza dos funciones fundamentales:

Por un lado, periódicamente revisa las estadísticas sobre el uso de la CPUpor cada proceso. Siguiendo este criterio, procede a ajustar el número queindica el máximo de páginas físicas asociadas a cada uno. A aquellos procesoscon poca actividad se les bajará el número (lo que acarreará un descargue desus páginas físicas, si las tiene, cuando sean necesarias), y a aquellos conmucha carga se les subirá el número.

Por otro lado, y también de forma periódica, roba a los procesos páginas físicas,elegidas de entre las menos recientemente usadas por cada uno. Esteprocedimiento se reliza a la frecuencia necesaria para que los procesos no seralenticen demasiado por los fallos de página. El objetivo de esto es manteneruna reserva de páginas para que una repentina demanda no ocasione una caída enprestaciones del sistema completo. Por ejemplo, cuando se inicia un procesonuevo se suele requerir una cantidad considerable de páginas.

Para llevar a cabo estas tareas, las páginas físicas se clasifican en unade cuatro listas que son mantenidos por el gestor del conjunto de trabajo:

    • lista de páginas modificadas
    • lista de páginas no activas
    • lista de páginas liberadas
    • lista de páginas a cero

Cada página que el gestor roba a un proceso es borrada su lista de menosrecientemente usadas e incluida en la lista de modificadas (y las entradascorrespondientes de la TIP marcadas como no válidas, de forma que se produzcafallo de página al acceder el proceso a dichas direcciones). Dicha listacontiene páginas robadas que aún están en memoria RAM pero que no han sidoescritas a disco (al archivo de paginación). Cuando se produzca un fallo de página,si la dirección física correspondiente estuviera en una de estas páginas,simplemente se volvería a insertar en la lista del proceso y se ajustaría suTIP.

Cuando la lista de modificadas se hace suficientemente grande, otra parte delVMM (el escritor de páginas) copia algunas páginas de la lista al archivo depaginación, las borra de la lista de modificadas y las añade a la lista deinactivas. Ahí están las páginas que han sido robadas, que están en RAM yademás en el archivo de paginación. El tratamiento de un fallo de página aquítambién sería muy rápido y simple.

Cuando un proceso libera memoria, sus páginas físicas asociadas se añadena la lista de liberadas. Son, por tanto, potencialmente utilizables sinnecesidad de escribirlas en el fichero de swapping pero su contenido no ha sidoborrado (están tal y como las dejó el proceso propietario). Periódicamente,estas páginas van siendo inicializadas con ceros,y añadidas a la lista de páginasa cero. El mecanismo de inicialización es para proteger la intimidad delantiguo proceso propietario. Cualquier página que se entrega a un proceso ha dehaber sido convenientemente inicializada.

Cuando un proceso requiere memoria física, el VMM comienza cogiendo páginasde la lista de inicializadas. Cuando está vacía, toma de la lista deliberadas, y las inicializa. Cuando ésta se vacía, toma de la lista deinactivas, y las inicializa. Sólo como última opción recurre a lasmodificadas. Estas últimas requieren escritura en el archivo de paginaciónjunto con inicialización, lo cual es un proceso lento.

En ambientes en los que la memoria es escasa, el gestor del conjunto detrabajo se centra en mantener un conjunto aceptable de páginas disponibles, másque en revisar las estadísticas de uso de la CPU.

Como valores aproximativos, podemos señalar que si el número de páginas acero más las liberadas más las inactivas suman menos de 20, el gestor robarápáginas a procesos que comparten la CPU. Si el número de modificadas superalas 30, procederá a descargar algunas a disco, pasándolas a inactivas.

Archivos Asignados en Memoria

Estudiemos ahora cómo el SO utiliza esta facilidad para cargar el código deun ejecutable y sus bibliotecas DLL asociadas.

Un archivo asignado en memoria es todo aquel archivo para el que se hareservado una región del espacio de direcciones virtuales de un proceso. Puedeestar asignado el archivo completo o sólo una porción del mismo (llamadavista).

En principio, el VMM no asigna ninguna página física para el archivoasignado en memoria. El proceso simplemente supone que en ciertas direcciones desu espacio tiene cargado el fichero, así que cuando acceda a alguna se produciráun fallo de página. Es entonces cuando el VMM le asigna algunas páginas físicasy las copia desde el disco (paginación bajo demanda, como comentábamos antes).

La gestión del VMM de los archivos asignados en memoria es como cualquierotra región del espacio direccionable del proceso, excepto que el swapping sehace directamente sobre el archivo (o sea, el archivo de intercambio es elpropio archivo asignado en memoria).

Cuando se arranca un proceso con su código grabado en un fichero, el VMMasigna automáticamente dicho fichero en el espacio de direcciones del proceso.También asigna todas las bibliotecas incluidas explícitamente y todas aquellasa las que se hace referencia en el código. Dentro del ejecutable existe unatabla llamada tabla de activación imagen, incluida por el enlazador, cuyasentradas contienen las funciones de biblioteca que se llaman durante el código.Una vez que se cargan las DLL (bibliotecas) en el espacio, el VMM completa latabla escribiendo para cada entrada la dirección que ocupa la correspondientefunción en el espacio del proceso. Por tanto, cada llamada a función implicauna búsqueda en la tabla.

Supongamos ahora que se arranca una segunda instancia del mismo proceso.Entonces el VMM pagina en

el espacio de direcciones del nuevo proceso el fichero y las DLL, pero novuelve a asignar páginas físicas, sino que ambas instancias comparten todo, almenos en principio. La ventaja de esto es ahorrar memoria, pero el inconvenientemás claro es que si uno de los procesos modificara, por ejemplo, algunavariable global de su segmento de datos, el otro la tendría igualmentemodificada. Esto ocurre evidentemente también él la pila e incluso en el mismocódigo (por ejemplo al ejecutar un depurador sobre una de las instancias parameter puntos de ruptura, se modificaría el código, lo cual implicaría que enla otra también).

Para solucionar el problema, Windows NT (y también UNIX) tiene una propiedaddenominada "copiar antes de escribir". El VMM intercepta cualquierinstrucción de escritura en el archivo mapeado en memoria por parte de lasinstancias. Cuando ocurre, asigna una o varias páginas físicas para lainstancia escritora, y copia los contenidos de las páginas originales en lasnuevas. A partir de ahora, esa instancia posee su propia región del archivopara modificar a su antojo. Análogamente para datos y pila.

UNIX también trabaja así, aunque duplica las zonas de datos y pila pordefecto, de forma que múltiples instancias comparten, en principio, sólo el código.

Con respecto a la tabla de activación imagen, decir que el VMM asigna lasDLL por defecto en direcciones fijas dentro del espacio de direcciones delproceso. Así, múltiples instancias del mismo pueden compartir la misma tabla.No obstante, un proceso puede especificar la dirección base de cada DLL; en esecaso, el proceso tendría su propia tabla en memoria, con lo que resulta máseficiente que todos los procesos tengan las DLL asignadas en las mismasdirecciones.

Desde el punto de vista del programador, se pueden asignar en memoriaarchivos de hasta 264 bytes usando vistas del archivo.

El archivo se abre con CreateFile. Los primero es crear un objeto de asignaciónde archivo para él, con la función CreateFileMapping indicando el tamaño realdel archivo. Después podemos definir diferentes vistas, con CreateViewOfFile.La vista se abandona con UnmapViewOfFile (y fueza al VMM a escribir lasmodificaciones en disco).

Los archivos asignados en memoria son el único mecanismo de compartición dedatos entre procesos. Existe un archivo que crea el objeto de asignación, y elresto de los procesos usarán el mismo objeto referenciado por la funciónOpenFileMapping. Si como descriptor de archivo se pasa a las funciones0xFFFFFFFF, entonces el VMM usará el archivo de paginación como medio decompartición de datos.

En una red no es posible usar este mecanismo de compartición de datos, puesel SO no garantiza la coherencia de los mismos. Por ejemplo, una CPU en unordenador podría modificar el archivo en disco y otra en otro distinto tenerloen memoria, con lo cual no se percataría de la actualización.

Uso de Memoria Virtual por parte del Programador

Vamos a ofrecer unas pinceladas sobre cómo el programador puede hacer usoexplícito del mecanismo de la memoria virtual, y así hacer aplicaciones máseficientes. Se trata sin duda de una forma elegante de programar, ya que permitesituar objetos de grandes dimensiones en el espacio de direcciones del proceso,cuyo tamaño real se desconoce al tiempo de compilación. Por ejemplo, una hojade cálculo.

Consiste en dos etapas: la reserva y la asignación.

La reserva no es más que indicar al SO que una región del espacio dedirecciones del proceso se va a destinar a un determinado objeto u objetos. Portanto no hay ninguna correspondencia con memoria física. El VMM toma nota en unVAD (Virtual Address Descriptor) de la dirección de inicio, número de bytesreservados, y protección de la zona (en efecto, las páginas pueden tenerpermisos de lectura, lectura/escritura, o ninguno). Si el proceso accede a unade estas direcciones, se elevará una excepción. La reserva se hace siempre portrozos de 64 Kb.

La asignación consiste en hacer corresponder toda o parte de la memoriaantes reservada con memoria física. No obstante, el VMM no va a asignar memoriafísica inmediatamente, sino que simplemente actualizará el VAD para permitirque esa memoria sea ahora accesible, y se asegurará que en el archivo depaginación haya espacio suficiente. Cuando el proceso haga un acceso, seproducirá un fallo de página, y es en ese momento cuando el VMM asignará páginasfísicas (para la página que produzca el fallo y las vecinas) y actualizará laTIP del proceso.

El problema de usar memoria virtual explícitamente es que el programadordebe llevar una lista de la memoria que ha asignado de entre la que hareservado. Otra solución es instalar un manejador de excepciones, de manera queal acceder a una dirección reservada pero no asignada se eleve una excepción.El manejador de esa excepción hará la asignación y se continuará la ejecución.

Para reservar memoria se llama a la función VirtualAlloc pasándole elindicador MEM_RESERVE, y para asignar, pasándole MEM_COMMIT.

La memoria reservada o asignada se puede liberar con VirtualFree, peroentonces ha de liberarse por completo.

Con VirtualLock indicamos al VMM que no descargue una determinada página adisco cuando el proceso esté ejecutándose (aunque cuando no se ejecuteperdamos el control).

Por último señalar que existen funciones del API Win32 que permitenverificar si una dirección virtual tiene correspondencia física o no.

Bloques (heaps)

Los bloques de memoria son muy útiles cuando el programador no necesita usarmemoria virtual explícitamente. Podemos tener estructuras de datos distintas enbloques distintos de memoria, de manera que un fallo en la manipulación deestructuras de un tipo no repercuta en las demás.

Además, de este modo se gestionaría más eficientemente la memoria, ya queal borrar estructuras y escribir otras no se provocaría fragmentación internadentro del bloque (al ser todas las de un tipo del mismo tamaño). Una últimarazón sería él poder minimizar los fallos de página. Estructuras en un mismobloque son probables que compartan la misma página, luego podríamos acceder atodas las de un mismo bloque con sólo un fallo de página.

 

6. Sistema De Archivos

Windows NT soporta cuatro tipos de sistemas de ficheros (SF)disintos, y puede trabajar con los cuatro a la vez (un disco con variasparticiones, en cada una un SF distinto). Son los siguientes:

Sistema de Archivos

Sistemas Operativos Soportados

FAT

DOS, Windows NT, y OS/2

HPFS

OS/2 y Windows NT

NTFS

Windows NT

CDFS

Windows NT

 NTFS (New-Technology File System): Es el sistema de ficherosnativo de Windows-NT. Como características podemos señalar:

  • Permite nombres de archivo de hasta 255 caracteres, sensibles al tipo de letra.
  • Permite la gestión de medios de almacenamiento extraordinariamente grandes.
  • Incorpora mecanismos para garantizar la seguridad.
  • Soporta el concepto de enlace (por compatibilidad con el estándar POSIX).
  • Es capaz de recomponerse rápidamente después de una caída del sistema.
  • Soporta el estándar Unicode. 

El que usa MS-DOS y Windows 16 bits. Es el SF más pobre, yes se mantiene para dar soporte a las aplicaciones DOS.

HPFS (High-Performance File System): Es el que usa el sistema operativo OS/2.Se ha incluido para dar soporte a las aplicaciones OS/2 y complementar así alsubsistema del mismo nombre. No es capaz de recomponerse del todo bien despuésde una caída del sistema ni de asegurar la no corrupción de los datos.

CDFS (CD-ROM File System): Es un SF que Microsoft ha desarrolladoexclusivamente para montarse sobre los CD-ROM.

Vamos a centrarnos en el más importante de los cuatro: NTFS. Este sistema deficheros lleva incorporados muchos conceptos de teoría de bases de datosrelacionales.

Proporciona la seguridad, recuperación y tolerancia a fallos en base a laredundancia de datos. De hecho,

implementa los cinco primeros niveles del pseudo-estándar RAID. RAIDsignifica Redundant Arrays of Inexpensive Disks, algo así como "vectoresredundantes de discos baratos". Actualmente, el coste de losalmacenamientos masivos o secundarios es ínfimo, y ya se pueden encontrardiscos de varios Gb por menos de S/.500.00.

A eso se refieren, a mi entender, las siglas. RAID es una "norma"de facto que se basa fundamentalmente en conseguir la integridad de los datos abase de dividirlos en pedazos y repartir los pedazos entre varios discos, juntocon informaciones redundantes de comprobación de errores. Cada nivel ofrece unaestrategia distinta para conseguir la integridad. Los niveles son:

Nivel 0: los datos de cada fichero se dividen en porciones, las cuales sereparten en un orden fijo entre los distintos discos con los que cuente elsistema. Realmente aquí no se usan códigos de comprobación de errores.

  • Nivel 1: de cada disco se realiza una copia o espejo. Es la estrategia que da mayor fiabilidad (pero también, evidentemente, la más costosa).
  • Nivel 2: como el 0, pero un algortimo va construyendo una serie de códigos correctores de errores. Esos códigos son igualmente distribuidos entre unos discos destinados especialmente a ese uso.
  • Nivel 3: como el 2, pero no se usan códigos correctores sino un simple código de paridad, que puede ser guardado en un mismo disco para todos los ficheros.
  • Nivel 4: como el 3, pero dividiendo los ficheros en segmentos de datos más grandes.
  • Nivel 5: es el nivel más usual; es igual que el4, pero no usa un disco separado para almacenar los códigos de paridad, sino que divide igualmente esos códigos y los distribuye por los disco, intentando que no coincidan en la misma zona de disco datos de un fichero con sus códigos de paridad correspondientes.
  • Nivel 6: igual que el 5 pero se auxilia de elementos hardware, tales como controladoras de disco especiales, fuentes de alimentación. 

En NTFS, al igual que en los SF de UNIX, existe una serie de permisos sobre ficheros y directorios, que son los siguientes: lectura (R), escritura (W), ejecución (X), borrado (D), cambio de permisos (P) y ser el nuevo propietario (O). Todo fichero y directorio tienen un propietario, que puede conceder permisos sobre ellos. El Administrador del sistema puede tomar la propiedad de cualquier fichero o directorio sobre NTFS, pero no transferirla de nuevo a ningún otro usuario, a diferencia de UNIX, ni siquiera a su dueño original.

Sistemas de Archivos

Ventajas

Desventajas

FAT

Poco consumo de sistema. El mejor para discos y/o particiones de menos de 200MB.

El rendimiento decrece con particiones de más 200MB. No se pueden aplicar permisos sobre archivos y directorios.

HPFS

El mejor para discos y/o particiones entre 200 y 400 MB. Elimina la fragmentación almacenando en un solo bloque el archivo completo.

No es eficiente para menos de 200MB.No soporta hot fixing. No se pueden aplicar permisos sobre archivos y directorios.

NTFS

El mejor para volúmenes de 400MB o más. Recuperable (registro de transacciones), diseñado para no ejecutarle utilerias de reparación. Es posible establecer permisos y registro de auditoría sobre archivos y directorios.

No recomendable para volúmenes de menos de 400MB. Consume de 1 a 5 MB de acuerdo al tamaño de la partición.

 Ventajas y Desventajas de los Sistemas de Archivos

A continuación vamos a comentar las llamadas al sistema másusuales para crear ficheros, leer de ellos, escribir en ellos, etc.

Creación/Apertura de Ficheros

Para crear/abrir un fichero se usa la llamada al sistema

HANDLE CreateFile (LPTSTR lpszName, DWORD fdwAccess, DWORD fdwShareNode,LPSECURITY_ATTRIBUTES lpsa, DWORD fdwCreate, DWORD fdwAttrsAndFlags, HANDLEhTemplateFile);

lpszName: nombre del archivo a crear o abrir.

fdwAccess: especifica el modo de acceso al archivo: lectura (GENERIC_READ),escritura (GENERIC_WRITE), o ambos.

fdwShareMode: permisos que tendrá la compartición del archivo a abrir: 0(ningún proceso podrá abrirlo hasta que nosotros lo cerremos), FILE_SHARE_READ(otros procesos pueden abrirlo pero sólo para leer), FILE_SHARE_WRITE (sólopara escribir; no se suele usar), o una combinación de ambos.

lpsa: la típica estructura de seguridad de todo objeto en Windows NT. Sólotendrá sentido si el archivo se crea en un SF que soporte seguridad, como NTFS.

fdwCreate: una serie de indicadores que especifican una acción:

CREATE_NEW: crea un archivo nuevo, y da error si ya existe

CREATE_ALWAYS: crea un archio nuevo,y si existe lo machaca

OPEN_EXISTING: abre un archivo, y da error si no existe

OPEN_ALWAYS: abre un archivo y si no existe lo crea

TRUNCATE_EXISTING: si el archivo exisye, lo abre pero truncando su tamaño a0 bytes; si no existe, da una error.

fdwAttrsAndFlags: sirve para dar atributos al fichero (sólo si lo estamoscreando) y activar ciertas banderas.

Veamos algunos.

Atributos:

FILE_ATTRIBUTE_HIDDEN: archivo oculto

FILE_ATTRIBUTE_NORMAL: archivo sin atributos especiales

FILE_ATTRIBUTE_READONLY: archivo de sólo lectura

FILE_ATTRIBUTE_SYSTEM: archivo del sistema

FILE_ATTRIBUTE_TEMPORARY: archivo temporal; el Executive intentarámantenerlo en RAM tanto como le sea posible

FILE_ATTRIBUTE_ATOMIC_WRITE: para indicar que los datos de este archivo soncríticos; eso hará que el Executive aumente la frecuencia con que escribeestos datos de RAM a disco.

A propósito de los dos últimos indicadores, comentar que el Executive noescribe a disco inmediatamente los cambios realizados a un archivo en RAM, puesdegradaría las prestaciones del sistema. Usa un mecanismo de escrituradiferida, de manera que se escribe a disco cuando se cierra el archivo, o cuandoel sistema está desocupado, o cuando es necesario hacer swapping. Para losficheros cuyos datos son críticos, necesitamos que las modificaciones seanescritas rápidamente a un soporte no volátil, por si el sistema se cayera.

Banderas:

FILE_FLAG_NO_BUFFERING: con esta bandera le indicamos al Executive que nogestione buffers de memoria con relación a la entrada/salida de este archivo,sino que lea y escriba directamente a disco.

FILE_FLAG_RANDOM_ACCESS: queremos acceso directo al archivo.

FILE_FLAG_SEQUENTIAL_SCAN: acceso secuencial.

FILE_FLAG_WRITE_THROUGH: con este indicador, el SO enviará a disco los datosque hayan sido modificados en memoria, pero los mantendrá en memoria paraacelerar las lecturas

FILE_FLAG_POSIX_SEMANTICS: acceso al archivo según el estándar POSIX (porejemplo, sensible al tipo de letra)

FILE_FLAG_BACKUP_SEMANTICS: cuando un proceso solicita abrir un archivo, elSO normalmente realiza ciertos tests de seguridad para comprobar si el procesotiene o no los permisos necesarios. Con este indicador se anulan ciertos tests,de manera que el SO comprueba si el proceso tiene permiso para acceder alarchivo, y si es así, le permite el acceso pero sólo para realizar una copiade seguridad. Aunque tenga permiso de escritura, le será anulado.

FILE_FLAG_OVERLAPPED: los accesos a los archivos suelen hacerse de manera síncrona(el subproceso duerme hasta que se consuma el acceso). Con este indicador sepermite realizar E/S asíncrona, con lo que el subproceso seguirá ejecutándosey el SO le informará cuando la E/S finalice.

hTemplate: el descriptor de un archivo ya abierto; si no es NULL, losatributos y banderas de dicho archivo serán asignados a los de nuestro archivo.

La llamada retorna el descriptor al objeto archivo, o -1 si hubo algúnerror.

Cierre de Ficheros

Se usa la misma llamada que para cerrar un descriptor a cualquier objeto. ElSistema Operativo decrementará el contador de uso del archivo, y si es 0 locerrará definitivamente.

BOOL CloseHandle (HANDLE hObject);

Lectura/escritura a ficheros

Windows NT permite que los subprocesos hagan E/S a ficheros de manera síncronao asíncrona. EL modo síncrono es el habitual: un subproceso inicia una operaciónde E/S sobre un fichero; el Executive lo pondrá a dormir hasta que esa E/S decomplete. En cambio, en el modo asíncrono, el subproceso que inicia la operaciónpuede seguir ejecutándose, y cuando necesite los datos de la E/S se pondrávoluntariamente a esperar, de manera que si para ese tiempo la E/S se hacompletado, obtendrá los resultados inmediatamente.

Se usan las mismas llamadas al sistema para ambos tipos de acceso. En dichasllamadas existirá un parámetro de entrada (lpOverlapped) que, si es NULL,indicará que la llamada es acceso síncrono; si no, indicará acceso asíncrono,dando la dirección de una estructura OVERLAPPED que tiene el siguiente formato:

typedef struct _OVERLAPPED{

DWORD Internal;

DWORD InternalHigh;

DWORD Offset;

DWORD OffsetHigh;

DWORD hEvent;} OVERLAPPED;

Internal: cuando la E/S se completa, el sistema guarda en esa palabra unestado interno.

InternalHigh: cuando la E/S se completa, el sistema guarda ahí el número debytes transferidos.

Offset,OffsetHigh: indican la posición del byte del archivo donde queremoscomenzar el acceso.

hEvent: el descriptor (opcional) de un objeto suceso.

Vamos a suponer que un subproceso A desea realizar E/S asíncrona sobre unfichero, y para ello inicializa el parámetro lpOverlapped de la llamada con ladirección correspondiente a una estructura OVERLAPPED. Entonces sigue ejecutándose.Cuando al Executive le llega la petición de E/S sobre el fichero, pone elestado de este objeto a no señalado. Cuando la E/S finaliza, lo pone a señalado(esto ya lo vimos en el capítulo de los procesos). En algún momento, Anecesita los datos de la E/S que inició, con lo que se pone a esperar a que elobjeto archivo se ponga a estado señalado (para lo cual usará una llamada tipoWaitFor...Object(s), como ya explicamos). Si, en el momento de hacer la llamadaa E/S, el subproceso A hubiera especificado en hEvent un descriptor a un suceso,el Executive pondría a señalados tanto el objeto fichero como dicho objetosuceso, con lo cual el subproceso A tendría la facilidad de esperar porcualquiera de los dos.

La utilidad de esto es en la situación de que el fichero es compartido, yvarios subprocesos pueden estar haciendo E/S sobre él y, por consiguiente, poniéndosea estado señalado/no señalado múltiples veces. Especificando un objeto sucesopropiedad de A, dicho subproceso sabrá que cuando el suceso esté señalado,seguro que se ha completado su operación de E/S y no la de otro.

Una vez explicados estos matices, pasamos sin más a describir el perfil delas llamadas de lectura/escritura, que son muy parecidas a las que usa UNIX:

BOOL ReadFile (HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,LPWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);

hFile: es el descriptor al archivo.

nNumberOfBytesToRead: es el número de bytes a leer.

nNumberOfBytesRead: es un parámetro de salida que indica el número de bytesque se leyeron en realidad.

lpOverlapped: elige modo síncrono/asíncrono; ya comentado

BOOL WriteFile(HANDLE hFile, CONST VOID * lpBuffer, DWORDnNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPEDlpOverlapped);

hFile: es el descriptor al archivo.

lpBuffer: apunta a un área de memoria donde se encuentran los datos aescribir.

nNumberOfBytesToWrite: número de bytes a escribir.

nNumberOfBytesWritten: número de bytes escritos en realidad.

lpOverlapped: elige modo síncrono/asíncrono; ya comentado.

Nos gustaría señalar que en los accesos síncronos existe un puntero delectura/escritura sobre un archivo para cada subproceso que esté accediendo almismo. Ese puntero lo asigna el SO en el momento de apertura del archivo cuandoun subproceso lo abre para accesos síncronos (o sea, sin especificar elindicador FILE_FLAG_OVERLAPED). El puntero se modifica al leer y al escribir. Enel caso de que el acceso síncrono sea también acceso directo, entonces esposible cambiar el puntero usando la llamada SetFilePointer, que no merece lapena comentar.

Nótese que en los accesos asíncronos no existe el puntero, por lo que hemosde indicar la dirección de inicio de cada acceso (recordemos que se indica enla estructura OVERLAPPED).

Existen unas llamadas de lectura/escritura extendidas (ReadFileEx yWriteFileEx), que son muy útiles a la hora de realizar una E/S asíncrona.Permiten que se les pase la dirección de una función de forma que, cuando laE/S asíncrona se complete, se salte a la ejecución de esa función. Para ello,el subproceso ha de estar esperando por el fin de la E/S con una funciónWaitFor...Object(s) extendida (WaitForSingleObjectEx o WaitForSingleObjectsEx).De hecho, WaitForSingleObject está construida internamente como una llamada aWaitForSingleObjectEx pasándole un parámetro que indica que no queremos usoextendido.

Atributos de Ficheros

Los atributos que se indican al crear un fichero en el parámetrofwdAttrsAndFlags pueden ser consultados con una llamada a:

BOOL GetFileInformationByHandle (HANDLE hFile, LPBY_HANDLE_FILE_INFORMATIONlpFileInformation);

Esta llamada devuelve en la estructura apuntada por lpFileInformation toda lainformación relativa al fichero cuyo descriptor es hFile. La estructura tienelos siguientes campos:typedef struct _BY_HANDLE_FILE_INFORMATION {

DWORD dwFileAtributes;

FILETIME ftCreationTime;

FILETIME ftLastAccessTime;

FILETIME ftLastWriteTime;

DWORD dwVolumeSerialNumber;

DWORD nFileSizeHigh;

DWORD nFileSizeLow;

DWORD nNumberOfLinks;

DWORD nFileIndexHigh;

DOWRD nFileIndexLow;} BY_HANDLE_FILE_INFORMATION;

dwFileAttributes: los atributos del fichero que se pasaron en el parámetrofdwAttrsAndFlags en el momento de su creación (ver CreateFile)

ftCreationTime: fecha de creación del fichero

ftLastAccessTime: fecha del último acceso al fichero

ftLastWriteTime: fecha de la última escritura al fichero

dwVolumeSerialNumber: número de serie del volumen donde se encuentra elfichero

nFileSizeHigh, nFileSizeLow: 64 bits que indican el tamaño del fichero; portanto, Windows NT permite ficheros de hasta 264 bytes

nNumberOFLinks: número de enlaces del fichero; este parámetro asegura lacompatibilidad con el estándar POSIX. Recordemos que en UNIX cada fichero tieneun número de enlaces que indican los distintos nombres que referencian al mismofichero dentro del sistema de ficheros. Así se evita la redundancia de datos.

nFileIndexHigh, nFileIndexLow: es un identificador único que el Executiveasocia a un fichero en el momento de que algún subproceso lo abre. Si elsistema se apaga y se enciende, el identificador puede no ser el mismo. Sinembargo, en la misma sesión, procesos distintos leerán el mismo identificador.Esto es útil para determinar si dos descriptores distintos referencian enrealidad al mismo fichero dentro de un volumen (basta hacer sendas llamadas aGetFileInformationByHandle y ver si el identificador y número de volumencoinciden en las estructuras devueltas por cada una).

Bloqueo de Archivos

Otra llamada muy importante es la que permite el bloqueo de todo o parte deun fichero, de manera que ningún otro subproceso pueda acceder a la regiónbloqueada.

La llamada para bloquear es:

BOOL LockFile (HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFIleOffsetHigh,DWORD cbLockLow, DWORD cbLockHigh);

hFile: descriptor al archivo a bloquear.

dwFileOffsetLow, dwFileOffsetHigh: dirección de comienzo de la región abloquear.

cbLockLow, cbLockHigh: tamaño de la región a bloquear.

La llamada para desbloquear es:

BOOL UnlockFile (HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFIleOffsetHigh,DWORD cbUnlockLow, DWORD cbUnlockHigh);

Los parámetros son análogos a los anteriores. Es necesario que unsubproceso desbloquee un área que previamente bloqueó antes de que finalice.En caso contrario, estará impidiendo el acceso al fichero a todos los demássubprocesos.

Existen versiones extendidas de ambas llamadas (LockFileEx y UnlockFileEx)que permiten establaces bloqueos pero sólo de escritura (otros subprocesos podránleer el área bloqueada, pero no escribir en ella).

 

7. Entrada Y Salida

A lo largo de los capítulos precedentes hemos hablado de losdistintos aspectos de la E/S: gestión de las caches, E/S síncrona y asíncrona,drivers de dispositivo, nivel de abstracción de hardware, ficheros y sistemasde ficheros, por citar algunos. Cuando describíamos el administrador de E/S delExecutive, hablamos también de que se encargaba de gestionar los mecanismosrelacionados con la red. Me parece conveniente dedicar parte de este último capítuloal tema de las comunicaciones en Windows NT, por tratarse de uno de los aspectosdonde más fuertemente brilla este SO.

Windows NT soporta trabajo en red con varios protocolos decomunicaciones. Lo más importante es que las facilidades de red estánintegradas en el SO, lo que lo distingue de DOS y de la mayoría de lasversiones de UNIX, en los que las interfaces con la red eran un añadido al SO,y frecuentemente no se adaptaban del todo bien al mismo.

Vamos a describir brevemente qué ocurre en cada uno de losniveles de implementación del modelo OSI:

En el nivel 0 aparece un dispositivo que es la tarjeta deinterfaz a la red (Network Interface Card, NIC). El NIC conecta el bus internode la máquina con la red, sirviendo de interfaz entre el nivel 0 y el 1 (nivelfísico). Es contemplado por el SO como un periférico más, controlado a travésde su driver correspondiente.

En el nivel 2 (nivel de enlace de datos) aparece un softwarellamado NDIS (Network Device Interface Specification), que es una interfaz entrelos drivers de dispositivo del NIC y los protocolos de transporte.

En los niveles 3 (nivel de red) y 4 (nivel de transporte)Windows NT sitúa el software de los protocolos de transporte. Soporta TCP/IP,NBF, NWLink, DLC y AppleTalk.

En el nivel 5 (de sesión) aparecen dos interfaces con losprotocolos de transporte, que son los Windows Sockets (WinSock) y la NetBIOS.

Un socket es un mecanismo para establecer una conexión entredos máquinas. Actúa como una especie de tubería bidireccional para los datos.Fueron introducidos por primera vez por el UNIX de Berkeley, y Windows NTincorpora una versión especial llamada WinSock. Se utilizan cuando se quiereuna comunicación a través del protocolo TPC/IP, IPX/SPX.

La interfaz NetBIOS es usada por aquellas aplicaciones quedeseen usar protocolos que se adapten a NetBIOS (como el NBF). Establececonexiones entre distintas máquinas de la red y se encarga de que la transmisiónsea fiable una vez establecida la conexión.

En la misma capa de sesión están dos subsistemas integralesgestionados por el administrador de la E/S, denominados el redireccionador y elservidor. El redireccionador es el responsable de enviar peticiones de E/S a lolargo de la red, cuando el fichero o dispositivo solicitados son remotos. Alservidor le llegan peticiones desde los redireccionadores clientes, y lasgestiona de modo que alcancen su destino. Tanto servidores comoredireccionadores son implementados como drivers del sistema de ficheros. Así,cuando un proceso quiere realizar una E/S, usará las mismas llamadas al sistemapara acceso local o remoto, con lo que no necesita conocer la ubicación delrecurso (fichero o dispositivo). Pueden existir múltiples parejas deredireccionadores-servidores ejecutándose concurrentemente.

En el nivel 6 (capa de presentación) define como se presentala red a si misma ante la maquina y sus programas y/o aplicaciones.

En el nivel 7 (capa de aplicación) existe un proceso llamadosuministrador por cada redireccionador de la capa 5. Cuando una aplicación haceuna llamada de E/S, un software llamado enrutador de suministradores (multipleprovider router) determina el suministrador adecuado, y le envía la petición.El suministrador, a su vez, se la pasará al correspondiente redireccionador.Por ejemplo, el gestor de ficheros (del administrador de E/S) es una aplicaciónque usa los servicios de los suministradores.

El último tema sobre E/S que vamos a tratar es la gestiónde entradas del usuario (mediante teclado o ratón). Cuando el sistema searranca y se crea el proceso subsistema Win32, este proceso crea a su vez unsubproceso llamado subproceso de entrada inicial (Raw Input Thread, RIT), quepor lo general está inactivo. Cada vez que un usuario pulsa una tecla, o mueveo pulsa el ratón, el driver de dispositivo correspondiente añade un sucesohardware a la cola de mensajes del RIT. Entonces, el RIT despierta, examina elmensaje, determina qué tipo de suceso es (WM_KEY*, WM_?BUTTON*, WM_MOUSEMOVE) ya qué subproceso va dirigido, y lo envía a la cola de mensajes de dichosubproceso. Para determinar el subproceso destino, el RIT examina sobre quéventana se encontraba el ratón cuando se produjo el suceso, y determina quésubproceso es el propietario de ese objeto ventana. Si es una secuencia deteclas, el RIT busca qué subproceso está actualmente en primer plano, y a élle mandará el mensaje.

No obstante, el RIT también monitoriza qué tipo de entradaes, para que de esta manera se pueda cambiar de contexto (Alt-Tab), o llamar alproceso Administrador de Tareas (si Ctrl-Esc) o visualizar la ventana de diálogode la seguridad (si Ctrl-Alt-Del), etc.

 

8. Windows Nt 5

En la versión 4.0, Microsoft nos dio una alegría al cambiarla interfaz gráfica de Windows NT y sustituirla por Indy, la bonita GUI deWindows 95. Desgraciadamente, NT 4.0 no incluía muchas de las cosas que se veníananunciando desde hacía tiempo, lo que nos dejó un sabor agridulce.

En Windows NT 5.0, Microsoft da un paso de gigante,incluyendo las siguientes novedades importantes:

  • Servicios de Directorio al estilo de X.500.
  • Modelo de Objetos de Componentes Distribuidos (DCOM).
  • Sistema de seguridad Kerberos. 

Servicios de Directorio: Active Directory

NT 5.0 incluye un servicio de directorio llamado Active Directory, basado enDNS (Domain Name Server) y LDAP (Lightweight Directoy Access Protocol).

El protocolo DNS da una manera de nombrar máquinas situadasen cualquier parte del planeta y nos permite conocer sus correspondientesdirecciones IP, gracias a que estructura los nombres de las máquinas jerárquicamentepor dominios, y cada dominio conoce potencialmente las direcciones IP de las máquinasque pertenecen a él. Si quiero conocer la dirección de la máquinami_servidor.dom1.edu, preguntaré a algún servidor del dominio edu, el cual, ola sabe directamente, o preguntará a algún servidor de dom1, y así.

Con Active Directory vamos a poder localizar cualquier objetollamándolo por su nombre, y acceder a información sobre él. Un objeto seráalgo heterogéneo: una máquina en Internet, un fichero, o un proceso en ejecución.La información sobre ese objeto dependerá de la clase a la que pertenezcadicho objeto (por tanto será también algo heterogéneo). El pegamento queaglutina todo esto se llama Active Directory.

La idea no es nueva: el sistema de directorios X-500 permitealgo parecido, pero su complejidad ha hecho que no esté muy difundido entre lossistemas operativos. Por ello se desarrolló LDAP, una versión simplificada deX-500.

En Active Directory va a tener, para cada dominio de nuestraLAN, un nombre de dominio al estilo DNS, y uno o varios servidores de dominio(llamados controladores de dominio). Cuando LDAP sea, al igual que DNS, un estándar,podremos acceder a la base de datos de directorios del servidor Active Directoryusando un cliente UNIX, OS/2 o Macintosh.

Tener varios controladores de dominio asociados al mismo dominio interesacuando necesitemos alto rendimiento y baja tasa de errores. Cada controlador vaa almacenar la misma base de datos del dominio del directorio. Active Directoryasegura la integridad de esas BD, de manera que actualizar una implique laactualización de cada una de sus copias. Para ello se usa un protocolo decomunicación entre controladores. La actualización de las copias se realiza sólosobre los datos modificados.

La replicación se realiza vía RPCs cuando estamos en un ámbito local, conalta fiabilidad y baja tasa de errores. Para redes a través de líneas telefónicas,se ha incluido la opción del correo electrónico como método para que loscontroladores se intercambien información de replicación.

En una LAN, la replicación se produce cada 5 minutos. En una WAN, eladministrador puede ampliar el intervalo para aumentar así las prestaciones.

Existen varias alternativas a la hora de elegir una API para los clientesActive Directory, destacando ADSI (Active Directory Sservice Interface).

Modelo de Objetos de Componentes Distribuidos (DCOM)

DCOM es una extensión natural a COM. COM es un estándar para la comunicaciónentre objetos independientemente del lenguaje en el que hayan sido escritos (porejemplo, objetos Java con obejtos C++). El objeto cliente accederá a los métodosdel objeto servidor a través de interfaces COM normalizados. Quizás nos suenemás el nombre de componentes ActiveX.

DCOM extiende lo anterior a un ámbito de red; los objetos a comunicarse notienen porqué compartir la misma máquina.

Pero esto no es nuevo: lo podíamos hacer desde hacía tiempo con las RPC. Dehecho, DCOM está construído sobre las RPC; se trata de un estándar de másalto nivel, con el que podremos escribir aplicaciones distribuidas en un entornode red sin necesidad de conocer todos los entresijos de las RPC, y además conun enfoque orientado a objetos. De hecho, Microsoft también se refiere a DCOMcomo Object RPC (ORPC).

DCOM se incluyó a Windows NT en su versión 4.0 (también salió en 1.996una versión para Windows 95), y actualmente la empresa Sofware AG prevé lanzarversiones para Solaris, Linux y otros sistemas a finales de este año. Con estotenemos que DCOM se está convirtiendo en un estándar importante en laindustria, y se podrá utilizar para comunicación entre objetos corriendo ensistemas operativos distintos.

Entonces, ¿qué aporta NT 5.0?

Supongamos que tengo un objeto servidor subsumido en unproceso en mi máquina servidora, y que un cliente quiere acceder a alguno delos métodos que mi objeto exporta como públicos. Entonces, el componente DCOMlocaliza él solito al objeto servidor en la red, y le manda una RPC. DCOMencuentra el objeto servidor en la red de dos posibles maneras:

En Windows NT 4.0, el cliente ha de conocer dónde está elservidor (lo tiene escrito en el Registro) y se lo dice a DCOM (trivial).

En Windows NT 5.0, DCOM usa Active Directory para hallar ladirección del objeto. Ésta es la gran ventaja sobre el caso anterior. Ademásde la dirección, puede encontrar más información sobre el objeto servidor.

Servicios de Seguridad: el estándar Kerberos

En UNIX, de la seguridad se encarga un módulo llamadoKerberos, desarrollado por el MIT como parte del Proyecto Atenas. Kerberos esactualmente un estándar en la industria, y Microsoft ha implementado la versión5 de la norma en NT 5.0.

Como sabemos, NT soporta varios protocolos de seguridad.Existe, no obstante, una interfaz común que los aglutina (la SSPI, SecurityService Provider Interface), y que proporciona una API común a los nivelessuperiores. En NT 4.0, la API cubre los protocolos SSL (Secure Sockets Layer,junto con su versión PCT) y NTLM (NT Lan Manager). En NT 5.0, Kerberos se uneal grupo. Los usuarios del nivel de seguridad son otros protocolos, que, usandola API SSPI, acceden a los servicios que ofrece ese nivel, eligiendo elprotocolo que deseen de entre los de la lista. Ejemplos de protocolos clientesson HTTP, LDAP, CIFS (usado por el Sistema de Ficheros Distribuido) y RPC.

En entornos de red, las aplicaciones usan primordialmente elprotocolo NTLM, que da autentificación, integridad de datos y privacidad. Estova a cambiar con la introducción del estándar Kerberos.

Kerberos, al igual que NTLM, proporciona autentificación,integridad de datos y privacidad. Entre las mejoras que hace a NTLM se encuentrala autentificación mutua, es decir, que tanto el cliente ha de probar suidentidad al servidor como el servidor al cliente. Cada dominio de la red va atener su servidor Kerberos, que utiliza la base de datos de Active Directory,con lo que se habrá de ejecutar sobre la misma máquina que el controlador dedominio. También puede estar replicado dentro del mismo dominio.

De manera muy general, podemos decir que un usuario que deseeacceder a servicios de una máquina remota debe primero hacer logon sobre elservidor Kerberos del dominio correspondiente (o sobre alguna de sus copias, sicabe).

Si los procesos de identificación y declaración deprivilegios son correctos, Kerberos entrega al cliente un "ticket queconcede tickets" llamado TGT (ticket-granting ticket) de acuerdo a losprivilegios del cliente. Usando ese ticket, el cliente podrá de nuevo solicitara Kerberos otros tickets para acceder a determinados servidores del dominio.Kerberos e