Apéndice E: Introducción a Windows 95 APÉNDICE E. INTRODUCCIÓN A WINDOWS 95 E.1 INTRODUCCIÓN Windows 95 aporta novedades y mejoras, especialmente en los dos siguientes campos: • • Multitarea: quizá el apartado más novedoso y el más esperado por los programadores. Conceptos como: procesos, subprocesos (threads), espacios de memoria estancos, mecanismos de sincronización y de comunicación, ya están disponibles. Administración de la memoria virtual: aporta grandes mejoras en su administración. En cuanto al direccionamiento de memoria, al utilizarse el modelo plano de 32 bits, una gran cantidad de cosas son ahora mucho más simples. Novedoso también el concepto de ficheros mapeados en memoria, con el que es posible olvidarse de las funciones read, write y seek y tratar los archivos como tablas normales. Nos ocuparemos del primero, pues es del que podríamos sacar mayor partido en nuestro sistema. E.2 EL PASO DE 16 BITS A 32 BITS Hay que advertir que Windows 95 (Win32) no es compatible con la extensión de 32 bits de Windows 3.11 (Win32s). El compilador utilizado, Borland C++ v. 4.5 permite desarrollar aplicaciones para Win32s, pero no para Win32. Existen versiones 32 bits (Win32s) de todas las librerías implementadas, excepto de tres: la librería referente a IDAPI, la de conexión con el HOST IBM y la que se encarga del envío de correo electrónico, pues dependen de librerías de terceros y no estuvieron disponibles durante el desarrollo del proyecto. También existe una versión 32 bits (Win32s) del intérprete. Pág. 1 Apéndice E: Introducción a Windows 95 Cuando se decide pasar una aplicación a 32 bits hay que tener algunas precauciones, la mayoría relacionadas con cambios en el tamaño de los tipos de datos. Por ejemplo, un entero (int) ocupa dos bytes en 16 bits y cuatro en 32 bits. Una solución es definir un nuevo tipo, digamos int16, de forma que ocupe dos bytes tanto en 16 como en 32 bits. Estos problemas con los cambios de tamaño se manifiestan sobre todo al trabajar con arrays de estructuras, en los accesos a disco en modo binario, si cambia el alineamiento de los datos (Data Alignment). Otro problema es que el compilador utilizado no permite usar las instrucciones de acceso a direcciones de entrada/salida inportb ni outportb (lo mismo ocurre con inport y outport) en 32 bits. Esto se debe claramente a un error del compilador, pues dichas instrucciones sí están disponibles en Visual C++ en su versión para Windows 95. La solución adoptada fue desarrollar unas funciones con el mismo nombre que estas instrucciones y codificarlas en ensamblador. E.3 MULTITAREA EN WINDOWS 95 Ante todo, veamos el concepto de proceso y subproceso. Cuando hay que cargar un programa, el sistema operativo primero crea un proceso, al que asigna todos los recursos del sistema, como: • • • • • • El espacio de direcciones de la aplicación, con los correspondientes componentes de la administración de la memoria, como tablas de páginas y tablas descriptivas. El espacio físico de que dispone el programa para su código, datos y pila. La línea de comando para activar el programa. Las variables de entorno de las que dispone la aplicación. El directorio de trabajo de la aplicación. Todos los recursos, como archivos y secciones en el disco duro, que la aplicación va haciendo suyos llamando durante su ejecución a las correspondientes funciones del API de Windows. El objeto del proceso acompaña a la aplicación durante toda su vida. Durante su ejecución, el proceso actúa como una especie de entorno exterior de la aplicación. Al mismo tiempo, sirve al sistema operativo como constructor, que le permite controlar y mantener separadas las aplicaciones que estén funcionando en paralelo. Si el usuario ha iniciado varias aplicaciones, eso significa que también hay varios procesos activos. Por lo general, uno por aplicación. Por debajo de los procesos se encuentran los subprocesos (threads). Estos son unidades de ejecución que materializan el auténtico desarrollo de la aplicación. No es el proceso lo que se ejecuta al iniciar la aplicación, sino un subproceso inicial denominado subproceso primario y que es creado automáticamente por el shell de Windows. Por eso, cada proceso posee al menos un subproceso que materializa su ejecución. Pág. 2 Apéndice E: Introducción a Windows 95 Si se quiere trabajar paralelamente con varios subprocesos bajo un solo procesador, hay que recurrir al principio de desplazamiento de tiempo. El procesador reparte cortos intervalos de tiempo entre la ejecución de diferentes subprocesos. Cuanto más rápido sea el cambio entre los diferentes subprocesos, antes se repiten estos en el ciclo y la impresión de simultaneidad es mayor. Sin embargo, el sistema tiene sus límites impuestos, pues cada cambio conlleva un cierto trabajo administrativo por parte del sistema operativo. En Windows 95, los desplazamientos de tiempo se han establecido en 20 milisegundos, lo que supone 50 cambios de subproceso por segundo. E.4 DIFERENCIAS RESPECTO A LA MULTITAREA COOPERATIVA Puesto que en el procedimiento descrito los subprocesos quedan detenidos en su ejecución y son interrumpidos arbitrariamente sin su intervención, se habla de multitarea prioritaria o expulsiva. Está en absoluto contraste con la multitarea cooperativa o no prioritaria, tal como es habitual en Windows 3.1 y también en Windows 95 en la ejecución de aplicaciones de 16 bits. Para mover la atención del procesador de una aplicación a otra, el núcleo de Windows 3.1 depende de la actividad de las aplicaciones. Sólo puede cambiar cuando una aplicación hace una llamada del tipo GetMessage() o PeekMesage(), devolviéndole así el control del procesador a Windows. El núcleo utiliza entonces esa posibilidad para continuar con la ejecución de otra aplicación. Por eso en Windows 3.1, las aplicaciones deben están concebidas para interpretar lo más rápido posible los mensajes recibidos. Cuanto más rápida sea esta operación, más rápidamente podrá pasar el control de una aplicación a otra. E.5 MULTITAREA COOPERATIVA Y PRIORITARIA JUNTAS Puesto que en Windows 95 es posible ejecutar aplicaciones tanto de 16 como de 32 bits, debe soportar dos sistemas multitarea diferentes: el prioritario de Win32 y el cooperativo de Win16. Por eso, todas las aplicaciones Win16 se ejecutan en lo que se denomina una máquina virtual (MV), la cual simula el entorno habitual de Windows de 16 bits. Dentro de esa MV, sólo se desarrolla multitarea cooperativa. Esta máquina virtual de 16 bits comparte el procesador con todas las demás aplicaciones de 32 bits activas, a través de la multitarea prioritaria. Pág. 3 Apéndice E: Introducción a Windows 95 La aplicación Win16 que se encuentre activa, obtendrá tiempo del procesador sólo cuando la MV en la que se desarrolla, obtenga a su vez un intervalo de tiempo. Dentro de ese intervalo, se puede cambiar a otras aplicaciones Win16 a través de la multitarea cooperativa. Tan pronto como la MV pierde su intervalo de tiempo, entra en acción la siguiente aplicación Win32. De esta manera, entre las aplicaciones Win16 se desarrolla la habitual multitarea cooperativa, sin que la multitarea prioritaria de Win32 tenga que sufrir por ello. E.6 VARIOS SUBPROCESOS EN UN SOLO PROCESO El modelo de la multitarea prioritaria en Windows 95 no se acaba en un subproceso por proceso. Una aplicación puede desarrollar la ejecución paralela de varias líneas de acción. La multitarea tiene lugar entonces, no sólo entre las diferentes aplicaciones, sino también entre los diferentes subprocesos. Los subprocesos se reparten básicamente todos los recursos de su proceso, acceden conjuntamente a las variables globales y comparten los recursos adquiridos en el marco del proceso, como son espacio en el disco duro, archivos, canales de comunicación, etc. Un subproceso, sin embargo, no puede acceder a los recursos de un subproceso de otro proceso, pues los procesos y sus subprocesos quedan estrictamente separados. Incluso los subprocesos dentro de un mismo proceso están separados, pues cada uno recibe su propia pila, en la que se depositan sus variables locales. Como cualquier otra aplicación, un proceso multi-subproceso se inicia con un solo subproceso y, durante su ejecución, produce otros subprocesos. La aplicación de varios subprocesos se emplea habitualmente en dos escenarios: • • Suprocesos de primer plano y de segundo plano: habitualmente el subproceso de primer plano es el responsable de la interacción con el usuario y el subproceso de segundo plano procesa los datos introducidos, los imprime, los guarda en el disco duro o bien realiza cálculos con ellos. Si bien la aplicación, en realidad, está ocupada con el procesamiento de los datos, permanece a la vez receptiva y puede reaccionar ante cualquier demanda del usuario. Aplicaciones cliente/servidor: un servidor debe contestar simultáneamente a varios clientes. Por cada consulta que recibe de un cliente se crea un subproceso para atenderla. Él es el responsable de ejecutar la consulta y desaparecerá tan pronto la haya contestado. El número de los subprocesos varía según el número de consultas que se hayan de ejecutar simultáneamente. Pág. 4 Apéndice E: Introducción a Windows 95 E.7 PRIORIDADES Y PROGRAMA DE CONTROL Cuando hay varios subprocesos que quieren estar activos a la vez, se plantea la cuestión de qué cantidad de tiempo de procesador se le ha de conceder a cada subproceso y en que momento. Si consideramos el caso anterior de los subprocesos de primer y segundo plano, el subproceso de primer plano debe reaccionar con la máxima rapidez a los requerimientos del usuario. Si el subproceso de segundo plano está activo, cuando el usuario pulsa una tecla se debería ejecutar de inmediato el subproceso de primer plano, independientemente de que este haya agotado ya su intervalo de tiempo. El resultado inevitable de esta situación es que se debe establecer un sistema de prioridades para los subprocesos. El subproceso de segundo plano, debe esperar cuando el subproceso de primer plano quiere estar activo. Qué subproceso se va a ejecutar y cuál no, es algo que decide el planificador (scheduler), uno de los componentes principales del núcleo de Windows 95, ya que es el que reparte el tiempo de procesador entre los diferentes subprocesos. Pero diferenciar entre subprocesos de primer plano y subprocesos de segundo plano no es suficiente para satisfacer las exigencias reales del mundo de la multitarea. En primer lugar, es necesario establecer diferencias más ajustadas. Además, un modelo de prioridades puramente estadístico, no es válido para un sistema dedicado al trabajo interactivo con el usuario. Un subproceso utilizado anteriormente con menos prioridad debe recibir de repente una prioridad mayor, porque el usuario ha abierto la ventana de una aplicación y ésta pasa a ser entonces la aplicación actual. E.8 CLASES SEGÚN PRIORIDADES Las diferentes prioridades de ejecución en Windows 95, se basan en cuatro clases según prioridades donde a un proceso siempre se le asigna una de esas clases. Los subprocesos resultantes del proceso obtienen todos, en principio, esa prioridad. Las clases según la prioridad se llaman: realtime, high, normal e idle. • • • Realtime: esta clase no es para programas de aplicación, sino para controladores de periféricos y otros componentes pensados para reaccionar de inmediato a los sucesos del hardware. High: esta clase debería ser utilizada sobre todo por las aplicaciones que esperen combinaciones de teclas. Es decir, por aquellos programas que esperan en segundo plano acciones, como la pulsación de una tecla de selección, y quieran reaccionar rápidamente a ellas. El administrador de tareas de Windows 95 (Alt+Tab) pertenece a este tipo de aplicaciones. Normal: es la clase que deberían utilizar las aplicaciones normales que no necesitan nada especial del planificador. Pág. 5 Apéndice E: Introducción a Windows 95 • Idle: los subprocesos de esta clase sólo se ejecutan cuando no hay subprocesos de otras clases preparados para ser ejecutados. Esta clase se utiliza exclusivamente para subprocesos destinados a realizar trabajos de mantenimiento en segundo plano, como son, por ejemplo, las operaciones de reorganización de la memoria. E.9 PRIORIDADES DENTRO DE LOS SUBPROCESOS Dentro de una clase de prioridad, determinada por el proceso, los subprocesos son sometidos de nuevo a diferentes prioridades. Aquí se dispone de cinco subclases: lowest, below normal, normal, above normal y highest. Todos los subprocesos se inician en la subclase normal y se modifican después con ayuda de las correspondientes funciones del API de Windows 95. La decisión sobre el reparto del tiempo de procesador no la toma el planificador dependiendo solamente de las prioridades estáticas definidas previamente para los subprocesos, sino de una prioridad dinámica que administra él mismo para cada subproceso. Primero, se inicializa con la prioridad estática y, a continuación, se adapta dinámicamente al sistema de acuerdo con las condiciones actuales. Con eso el subproceso no abandona la clase de prioridad de su proceso, pero puede pasar, por ejemplo, del nivel normal a highest si existe un evento en el sistema frente al cual debe reaccionar rápidamente. A cada nuevo intervalo de tiempo que se le da después, va perdiendo nivel, bajando de subclase hasta que alcanza de nuevo su prioridad inicial. Para que lo anterior funcione correctamente, los subprocesos pueden comunicarle al sistema que están esperando un determinado evento, por ejemplo, la pulsación de una tecla. Además los subprocesos pueden quedarse latentes a voluntad para volver a ejecutarse transcurrido un determinado tiempo. Por último, si en la cola de espera de mensajes no hay ningún mensaje para el subproceso, este queda detenido a favor de otro subproceso de prioridad igual o superior. E.10 SINCRONIZACIÓN Siempre que varios procesos o subprocesos trabajan conjuntamente en una tarea, aumenta la dificultad para que se pongan de acuerdo. Cuando varios subprocesos desean acceder a un recurso que puede ser utilizado al mismo tiempo únicamente por un solo subproceso, surgen los problemas. Para solucionarlo existe un grupo de objetos de sincronización. No entraremos en mucho detalle, pues su descripción se puede encontrar en cualquier texto sobre sistemas operativos o ejecución concurrente de aplicaciones: Pág. 6 Apéndice E: Introducción a Windows 95 • • • Semáforos y secciones críticas: sirven para poder acceder a un recurso en exclusión mutua. Su mal uso puede llevar al “bloqueo mortal” (deadlock), que se produce cuando dos o más subprocesos están bloqueados esperando una acción que debe realizar uno de ellos, que por estar bloqueado, nunca la realizará. Eventos: se utilizan cuando se desea que un subproceso espere un resultado específico, como por ejemplo, que otro subproceso realice un cálculo. Notificaciones de cambio y entrada de consola: materializan una forma singular de evento, con cuya ayuda, un subproceso puede tomar acciones. Pág. 7 Apéndice E: Introducción a Windows 95 APÉNDICE E.......................................................INTRODUCCIÓN A WINDOWS 95 1 E.1 INTRODUCCIÓN......................................................................................................1 E.2 EL PASO DE 16 BITS A 32 BITS .............................................................................1 E.3 MULTITAREA EN WINDOWS 95 ..........................................................................2 E.4 DIFERENCIAS RESPECTO A LA MULTITAREA COOPERATIVA..................3 E.5 MULTITAREA COOPERATIVA Y PRIORITARIA JUNTAS..............................3 E.6 VARIOS SUBPROCESOS EN UN SOLO PROCESO ..............................................4 E.7 PRIORIDADES Y PROGRAMA DE CONTROL ...................................................5 E.8 CLASES SEGÚN PRIORIDADES............................................................................5 E.9 PRIORIDADES DENTRO DE LOS SUBPROCESOS .............................................6 E.10 SINCRONIZACIÓN..............................................................................................6 Pág. 8