Marcando la diferencia

Conociendo cómo funciona el Sistema Operativo Microsoft Windows. Una perspectiva interna de Funcionamiento (I)


Si continúa leyendo el texto, encontrará explicaciones del Bucle de Mensajes de Windows y Sobre Multitarea Cooperativa  y Preemptiva, que hacen al contendido de este artículo.  Por de pronto vale decir que en los textos tradicionales referidos a nucleos de sistemas operativos, casi no son abordados topicos sobre Windows, dando mayor enfoque a sistemas operativos basados en Unix y sus derivados.  Una de las barreras quizas sea que el nucleo de Windows no es de codigo abierto y no son de dominio público para que los expertos puedan opinar sobre Windows en sí mismo. Pero no obstante, debemos abrir las sendas para comprender como funciona este maravilloso sistema operativo que todos utilizamos a diario. Sin olvidar las definciones que se deben aplicar o redefiniciones al pasar de un sistema operativo de 32 bits a 64 bits, cada vez que pasamos desde los 16 bits a 32 bit y ahora a los 64 bits presentan cambios tanto en la estructura de los programas como del mismo sistema operativos que también se deben tener en cuenta y sacarlos al tapete como topicos que se pueden ir abordando.

 

http://terabyteslibres.files.wordpress.com/2008/08/microsoft_windows.jpg 

Windows en sus inicios ha incorporado la multitarea Cooperativa, donde se supone que todas las aplicaciones funcionan correctamente y cooperan en el normal funcionamiento del sistema, respetando el uso de los recursos o utilizando los recursos en forma que no afecten  el normal funcionamiento del sistema. Parece un chiste decir que los programas funcionan correctamente todo el tiempo y no utilizan o comparten los recursos sin apropiarse todos de ellos por un gran periodo de tiempo, y que la comunicaciones entre distintos componentes tanto internos como externos refriéndonos al hardware funcionan correctamente. Como sabemos en la realidad esto no funciona es por tanto, que Microsoft  ha evolucionado desde una Multitarea Cooperativa a la Multitarea Preemptiva donde el sistema operativo administra todos los recursos, tiempos de ejecución y otras tareas para el normal funcionamiento del sistema.  La evolución del Sistema Operativo más utilizado en todo el mundo va mejorando cada día, en otro artículo estaremos hablando principalmente de las ventajas que se están viendo especialmente con el nuevo sistema operativo Windows 7, que  inclusive muchas empresas de hardware y software todavía no pueden ir al mismo ritmo de la potencia y lo que ofrece este nuevo sistema operativo.El otro punto que queremos hacer notar  corresponden con los Mensajes, Bucles de Mensajes de Windows. 

 Pensemos que cada mensaje que se envía al sistema es como si fuera una pelota de tenis, cada mensaje corresponde con una pelota de tenis.   

Las pelotas tienen marcadas una prioridad y una etiqueta que indica a que eventos dentro del sistema corresponden. Cada vez que mueve el ratón o pulsa una tecla o hace click sobre un botón se genera un evento.  Estos eventos son registrados y enviados para que los programas los puedan administrar, en último caso si las aplicaciones no las manejan el mismo sistema operativo trata de atenderlos para que todo el sistema pueda funcionar correctamente. 

Muchos usuarios suelen  reclamar y se preguntan que hace Windows Internamente. 

Evidentemente es un tema que hay que analizarlo correctamente, muchas de las aplicaciones desarrolladas muchas veces no utilizan los recursos limitados de forma prudencial, es por tal motivo que muchas veces ocurren  disparidades entre las mismas aplicaciones, otras veces ocurren diferencias de tiempo  para  las coordinaciones entre distintos tipos de hardware ( ya sea hardware contra hardware o hardware contra software) y el sistema operativo, sin hablar de que muchas veces los mismos equipos dejan de funcionar correctamente, y que existen una ensalada de diversos componentes de diferentes fabricas que aunque se suponen que se manejan bajo ciertos estándares a veces no son del tanto validas. 

A veces también por desconocimiento de los mismos usuarios que  sobrecargan más su propio sistema. 

Supondremos cada mensaje como una pelota de tenis que son colocados en un tubo para que luego cada pelota pueda ser lanzada a los jugadores que tendrán que atender a cada pelota. Los jugadores son las aplicaciones que tendrán que interceptar cada pelota o mensaje. 

Windows gestiona en la medida de sus posibilidades estas pelotas en el tubo, que son las Colas de Mensajes. Como cada pelota contiene la etiqueta que lo identifica y una prioridad asignada. Dentro del Tubo Windows va lanzando las pelotas a cada jugador de acuerdo con las prioridades que el va detectando. Lo que sucede es que muchas veces Windows debe reordenar las pelotas dentro del tubo para optimizar el funcionamiento del sistema.  

Problemas comunes por ejemplo son  las ordenes de paint o repaint  o refresh de pantallas que muchos desarrolladores no pueden gestionarlos correctamente  y resultado de ello sobrecargar la cola de mensajes. De igual manera muchos usuarios suelen sobrecargar la cola de mensajes enviando peticiones de paint o repaint  sin saberlo mediante ordenes de refresh que también sobrecargan el sistema. Quizás los usuarios pensando que así sus aplicaciones van ganando prioridad o se ejecutan con mayor velocidad, pero lo que están haciendo es lo contrario, están sobrecargando la cola de mensajes del sistema.

Como se explico en párrafos arriba, los problemas con el manejo de multitarea dependen en gran medida del hardware que utilizamos, de las aplicaciones que no usan correctamente los recursos como el refresh o uso de relojes internos o retardos que provocan la misma aplicación o querer apropiarse del mayor tiempo de los recursos que no favorecen el normal funcionamiento del sistema. 

Ahora, después de leer este texto, tendrías ya algunas ideas de que muchas veces los problemas no corresponden a defectos del mismo sistema operativo, evidentemente existe una carrera veloz entre diferentes desarrolladores de sistemas operativos hacia la minimización de los diversos problemas que estamos acostumbrados al utilizar un sistema operativo y las aplicaciones que  las soportan. 

Concepto Multitarea: 

Se llama multitarea al sistema operativo donde varios procesos pueden ser ejecutados al mismo tiempo compartiendo uno o más procesadores. 

Refiriéndonos sobre  los Tipos de multitarea: 

  • Nula: El sistema operativo es mono tarea.
  • Cooperativa: Los procesos de usuario son quienes ceden la CPU al sistema operativo a intervalos regulares. Muy problemática, puesto que si el proceso de usuario se cuelga y no cede la CPU al sistema operativo, todo el sistema quedará entonces colgado. Da lugar también a latencias muy irregulares, y la imposibilidad de tener en cuenta este esquema en sistemas operativos de tiempo real. Un ejemplo seria Windows, hasta la versión 3.11.
  • Preemptiva: El sistema operativo es el encargado de administrar el/los procesador/es, repartiendo el tiempo de uso de este entre los procesos que estén esperando para utilizarlo. Cada proceso utiliza el procesador durante cortos periodos de tiempo, pero el resultado final es prácticamente igual que si estuviesen ejecutándose al mismo tiempo.
  • Real: Solo se da en sistemas multiprocesador. Es aquella en la que varios procesos se ejecutan realmente al mismo tiempo, en distintos microprocesadores. Suele ser también preemptiva.  

Comprender el Bucle de Mensajes: 

¿Que es un Mensaje? 

Un mensaje es un valor entero.  (Ver API`s) puedes encontrar cosas como esta: 

#define WM_INITDIALOG                  0x0110 

#define WM_COMMAND                    0x0111 

 #define WM_LBUTTONDOWN           0x0201 

 Los mensajes son  usados para comunicar la mayoría de las cosas en windows, al menos en los niveles básicos. Si quieres que una ventana o control (el cual es una ventana especializada) haga algo, debes enviarle un mensaje. Si otra ventana quiere que vos hagas algo, entoces te envía un mensaje. Si ocurre un evento, como cuando el usuario mueve el mouse, presiona el teclado, etc... Entonces el sistema la envía un mensaje a la ventana afectada. Dicha ventana recibe el mensaje y actúa adecuadamente. 

Cada mensaje en windows puede tener hasta dos parámetros, wparam y lparam. Originalmente wparam tenía 16 bits y lparam tenía 32 bits, pero en Win32 ambos son de 32 bits. No todos los mensajes usan estos parámetros y cada mensaje los usa de manera diferente. Por ejemplo, el mensaje WM_CLOSE no usa ninguno de los dos y por lo tanto deberias ignorarlos. El mensaje WM_COMMAND usa ambos, wparam contiene dos valores HIWORD(wparam) es la notificación del mensaje (si se aplica) y LOWORD(wparam) es el ID del control o menú que envió el mensaje. lparam es el HWND (Windows Handle) del control que envió el mensaje o nulo (NULL) si el mensaje no proviene de un control. 

HIWORD( ) y LOWORD( ) son macros definidas por windows que simplemente retornan la palabra superior (High Word) y la palabra inferior (Low Word), respectivamente, de un valor de 32 bits. En Win32 una palabra es un valor de 16 bits, haciendo un DWord (palabra doble) un valor de 32 bits. 

Para enviar un mensaje puedes usar PostMessage( ) o SendMessage( ). PostMessage( ) pone el mensaje en la Cola de Mensajes y retorna inmediatamente. Esto significa que una vez que la llamada a PostMessage( ) se completa el mensaje puede o no puede haber sido procesado aún. SendMessage( ) envía el mensaje directamente a windows y no retorna hasta que windows haya finalizado de procesarlo. Si quisieramos cerrar una ventana, podríamos enviarle a un mensaje WM_CLOSE de la siguiente manera: PostMessage(hWnd,WM_CLOSE,0,0). Lo cual podría tener el mismo efecto que hacer click en el boton cerrar de la ventana. Observa que wparam y lparam son ambos 0. Esto es debido a que, como mencionamos, no se usan con el mensaje WM_CLOSE. 

Diálogos 

Una vez que comiences a usar cajas de diálogo necesitarás enviar mensajes a los controles para poder comunicarte con ellos. Puedes hacer esto primero através de GetDlgItem( ) (utilizando el ID como parámetro) para obtener el handle al control y luego usar SendMessage( ). O puedes usar SendDlgItemMsg( ), el cual combina ambos pasos. Como parámetros utilizamos el handle de la ventana y un ID de un hijo y SendDlgItemMsg( ) retorna el handle del hijo y le envía el mensaje. Ambas formas de enviar mensajes funcionan bien en todas las ventanas, no solamente en cajas de diálogo. 

¿Que es la Cola de Mensajes? 

Digamos que te encuentras ocupado manejando el mensaje WM_PAINT y repentinamente el usuario ingresa un gran cantidad de datos por el teclado. ¿Que debería suceder?. ¿Deberías interrumpir el procesamiento de WM_PAINT (dejar de dibujar la pantalla) para atender el teclado, o deberías simplemente descartar lo que el usuario ingresó por el teclado?. Error!, obviamente ninguna de éstas opciones son rasonables. Para esto tenemos la Cola de Mensajes. Cada vez que se recibe un mensaje, dicho mensaje es encolado en la cola de mensajes y cada vez que se quiere procesar un mensaje dicho mensaje es removido de la cola (valga la redundancia). Esto asegura que no se pierdan mensajes, si estás procesando uno, entonces los otros serán encolados hasta que los recuperes de la cola. 

¿Que es el Bucle de Mensajes? 

while(GetMessage(&Msg, NULL, 0, 0) > 0) 

    TranslateMessage(&Msg); 

    DispatchMessage(&Msg); 

  1. El Bucle de Mensajes llama a GetMessage( ), el cual busca en tu cola de mensajes. Si la cola de mensajes está vacía, tu programa se detiene y espera hasta que haya un mensaje (se bloquea).
  2. Cuando ocurre un evento, causando que un mensaje sea puesto en la cola (por ejemplo el sistema registra un click del mouse) GetMessage( ) retorna un valor positivo indicando que hay un mensaje para ser procesado y que ha llenado los campos de la estructura MSG que le pasamos.
  3. Tomamos el mensaje (en la variable Msg) y se lo pasamos a TransalateMessage( ), éste hace un proceso adicional traduciendo mensajes con teclas virtuales, en mensajes con caracteres. Este paso puede ser opcional, pero ciertas cosas no funcionarán si no lo utilizamos.
  4. Una vez que finalizamos de traducir el mensaje, se lo pasamos DispatchMessage( ). Lo que DispatchMessage( ) hace es tomar el mensaje, chequear a que ventana está destinado y buscar el Window Procedure de dicha ventana. Luego llama a dicho procedimiento enviando como parámetro el handle de la ventana, el mensaje, wparam y lparam.
  5. En el Windows Procedure chequeamos el mensaje y sus parámetros y luego hacemos lo que desamos con ellos. Si no estamos manejando dicho mensaje, por lo menos siempre llamamos a DefWindowProc( ) el cual realizará las acciones “por default” (lo cual significa que a veces no hace nada).
  6. Una vez que hallas terminado de procesar el mensaje el Window Procedure retorna, DispatchMessage() retorna y regresamos al comienzo del bucle.

Este es un concepto muy importante para los programas de windows. El Windows Procedure no es mágicamente llamado por el sistema, de hecho lo llamamos indirectamente através de DispatchMessage( ). Si deseas, puedes usar GetWindowLong( ) en el handle de la ventana a la cual está destinado el mensaje para buscar el Window Procedure de la misma y llamarlo directamente! 

while(GetMessage(&Msg, NULL, 0, 0) > 0) 

    WNDPROC fWndProc = (WNDPROC)GetWindowLong(Msg.hwnd, GWL_WNDPROC); 

    fWndProc(Msg.hwnd, Msg.message, Msg.wParam, Msg.lParam); 

He intentado esto con el código del ejemplo anterior y funciona. Sin embargo hay varios aspectos como la traducción UNICODE/ANSI, entre otros, que este método no tendrá en cuenta y probablemente haga fallar hasta la aplicación mas trivial. Por lo tanto hazlo como prueba pero no lo hagas en el código real. 

Observa que hemos usado GetWindowLong( ) para recuperar el Window Procedure asociado con la ventana, pero ¿por que no lo llamamos directamente?. Bien, nuestro bucle de mensajes es responsable de TODAS las ventanas en nuestro programa, esto incluye cosas como botones, listas, etc.. que tienen su propio Window Procedure asociado, por lo tanto necesitamos asegurarnos que llamamos al procedimiento correcto para una cierta ventana. Debido a que más de una ventana puede usar el mismo Window Procedure, usamos el primer parámetro (el handle de la ventana) para decirle al Window Procedure a que ventana está destinado el mensaje. 

Como puedes ver tu aplicación pasa la mayor parte del tiempo dando vueltas y vueltas en el bucle de mensajes donde alegremente envías mensajes a las felices ventanas que los procesarán. ¿Pero que haces cuando quieres que tu programa salga? Debido a que estamos usando un bucle while( ) si GetMessage( ) retornara FALSE (i.e 0), el bucle podría finalizar y de esta manera podríamos alcanzar el final de nuestro WinMain( ), es decir salir del programa. Esto es exactamente lo que PostQuitMessage() realiza; pone un WM_QUIT en la cola y GetMessage( ) en vez de retornar un valor positivo, llena la estrucura MSG y retorna 0. Hasta este punto el campo wparam de la variable Msg contiene el valor que le pasamos en PostQuitMessage( ) y podemos ignorarlo o retornarlo al WinMain( ) donde se usará como valor de salida cuando el programa finalice. 

IMPORTANTE: GetMessage( ) retornará -1 cuando encuentre un error. Asegúrate de recordar esto o te sorprenderá en algún momento… Aún cuando GetMessage( ) está definido para retornar un BOOL (Booleano), éste puede retornar valores distinos de TRUE o FALSE, debido a que BOOL está definido como UINT (unsigned int). Los siguientes son ejemplos de código que puede parecer que funciona pero no procesarán ciertas condiciones correctamente. 

    while(GetMessage(&Msg, NULL, 0, 0) != 0)

17 comentarios

  1. juan

    me gusta mucho tu blog…

    22 noviembre, 2012 en 5:04 AM

    • gRACIAS POR TUS COMENTARIOS…. QUE BUENO QUE TE GUSTE…😉

      22 noviembre, 2012 en 8:08 AM

  2. What a information of un-ambiguity and preserveness of precious
    know-how about unpredicted emotions.

    2 febrero, 2013 en 7:11 AM

  3. I have to thank you for the efforts you’ve put in writing this blog. I am hoping to see the same high-grade blog posts by you in the future as well. In truth, your creative writing abilities has motivated me to get my very own site now😉

    12 febrero, 2013 en 10:27 PM

    • Hi, my name is Walter Escurra, I’m Responsible for writing this blog.

      Pleasant for yours commentaries, Thanks to everyone.

      And God in yours hearth.

      Sincerily!!!

      13 febrero, 2013 en 8:26 AM

  4. Very nice post. I just stumbled upon your weblog and wished to say that I
    have truly enjoyed browsing your blog posts. In any case I will be subscribing to your feed and I hope you write again very soon!

    2 mayo, 2013 en 6:53 AM

  5. I loved as much as you will receive carried out
    right here. The sketch is tasteful, your
    authored material stylish. nonetheless, you command get bought an shakiness over that you wish be
    delivering the following. unwell unquestionably come more formerly again as exactly the same nearly very often inside
    case you shield this hike.

    8 mayo, 2013 en 10:05 PM

  6. Hi there! I just wanted to ask if you ever have any issues with hackers?
    My last blog (wordpress) was hacked and I ended up losing months
    of hard work due to no back up. Do you have any solutions to prevent hackers?

    13 mayo, 2013 en 9:30 AM

  7. Very good post! We are linking to this particularly great post on
    our website. Keep up the great writing.

    19 mayo, 2013 en 9:21 AM

  8. Pretty nice post. I just stumbled upon your weblog and
    wished to say that I’ve really enjoyed surfing around your blog posts. After all I’ll be subscribing to your
    rss feed and I hope you write again very soon!

    23 mayo, 2013 en 6:27 AM

  9. Wonderful post! We are linking to this great article on our website.
    Keep up the great writing.

    23 mayo, 2013 en 9:20 AM

  10. Generally I do not learn article on blogs,
    however I wish to say that this write-up very compelled me to try and do
    so! Your writing taste has been amazed me. Thanks, quite nice post.

    30 mayo, 2013 en 12:02 AM

  11. Nice post. I used to be checking continuously this weblog and I’m impressed! Very helpful info particularly the remaining section🙂 I handle such info much. I used to be looking for this particular info for a long time. Thank you and good luck.

    30 mayo, 2013 en 5:27 AM

  12. I all the time used to study post in news papers but now
    as I am a user of internet therefore from now I am using net for articles, thanks to
    web.

    7 junio, 2013 en 12:59 PM

  13. I’m gone to tell my little brother, that he should also pay a quick visit this webpage on regular basis to obtain updated from newest reports.

    12 junio, 2013 en 1:58 PM

  14. Pingback: vidente buena De Verdad

  15. joaco

    Increíble información. ¿De dónde sacás tanta información?
    Me gustaría aprender más sobre como funcionan los sistemas internamente (windows, Gnu/linux, BSD), que hace cada parte del sistema, ¿qué me recomendás?

    1 agosto, 2015 en 12:55 AM

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s