'' Procesos, threads e hilos

Por la Redacción de FoxPress




Qué es un Thread? ¿Qué es un Proceso? Un Proceso es algo que te resulta bastante familiar. Si lanzas Microsoft Word y VFP, entonces tienes dos procesos separados que están corriendo al mismo tiempo aunque sólo tengas una CPU. El sistema operativo asigna tiempo a cada uno de los procesos y pasa de uno a otro según le interesa. En un sistema multitarea no-preemptivo (un tarea es sinónimo de un proceso) tal como Windows 3.1, un proceso puede paralizar la ejecución de otro proceso, pues el sistema operativo pasa un mensaje a cada proceso y este lo interpreta, mientras un proceso interpreta un mensaje los demás procesos están detenidos. En un sistema multitarea preemptivo, la CPU realiza un reparto del tiempo de ejecución entre las intrucciones de todos procesos.

Una arquitectura de aplicación basada en un sólo proceso no funciona bien en un servidor de aplicaciones Web. Un usuario con un Browser en Hawaii hace un hit en tu Web y tu servidor Web empieza a procesar la petición. Al mismo tiempo viene otro usuario de Nueva zelanda, y tiene que esperar hasta que la primera petición ha finalizado. Una posible solución a este problema es tener múltiples procesos sirviendo a estas peticiones, de forma que puedan ser respondidas de forma más o menos simultanea. Esto es lo que hacen los CGI. (cada CGI crea un nuevo proceso que crea una página y a continuación termina.) Sin embargo, esto conlleva un uso intensivo en recursos y es ineficiente.

Una mejor solución es tener muchos threads (hilos) dentro de un solo proceso capaz de procesar las peticiones de la Web. Cada proceso tiene un thread principal, pero puede crear muchos threads privados para su propio uso. El sistema operativo no sólo es perfectamente feliz haciendo eso y saltando de un thread a otro dentro del mismo proceso sino que no asigna necesariamente un espacio de memoria a cada uno de los threats privados, mejorando considerablemente el uso de los recursos. Por esta razón los threads gozan de mucha eficiencia. La arquitectura ISAPI se basa en múltiples threads. Cada hit en la web usa uno de un pool de threads para responder a las peticiones.

Programación de múltiples Thread

Escribir código para múltiples threads es diferente de escribir un código para un sólo thread. Imaginate que mientras uno de tus procedimientos se está ejecutando, el procesador salta a otro thread que quiere ejecutar el mismo procedimiento. Este salto se podría producir en cualquier momento y es muy dificl de testear.

Considera el siguiente seudo código:

FUNCTION MyProc
*LOCAL myvar
Myvar = 44
If myvar = 44
	Myvar = 55
Endif
Return myvar

Con la orden LOCAL comentada, cual será el valor de esta función en un entorno multithread? Parece que 55. Sin embargo, puede ser que después de asignar el valor de 44, otro thread se podría ejecutar, cambiar el valor de myvar a 55, entonces tu thread partiría en la orden IF con myvar = 55. Una solución para solucionar esto es usar la orden LOCAL. Otra solución sería bloquear todos los otros threads con algún tipo de tecnica de sincronización. Los programas que se ejecutan con multiples Thread tiene que utilizar variables privadas para cada Thread y zonas críticas, semáforos y otros mecanismos para poder acceder de forma ordenada a las variables globales del programas.

Thread y Objetos COM

¿Qué sucede cuando un thread crea una instancia de un servidor COM y otro thread necesita llamar a un método de ese servidor?

Los Servidores Single threaded son el tipo de modelo de Thread para objetos COM más simple. Este es el único modelo disponible usando Windows NT 3.5. y el único que soporta VF5 (VFP5 era liberado en Agosto de 1996). En NT 3.5, si tenías multiples threads en un solo proceso, no podías usar un objeto COM. Un servidor COM usaba el mismo thread como cliente. El cliente no podía llamar al servidor COM usando un thread diferente. Esto hacía imposible crear servidores o clientes COM multi-threaded.

Con NT3.51 y Win 95 los Servidores y Clientes COM multithreaded ya son posibles. Con el modelo de Apartmentos (algunas veces llamado Single Apartment Model) se podían llamar a multiples objetos COM y todos los threads de un proceso pueden usar estos objetos COM. El Modelo de apartamentos Free-threaded o Multi-Threaded Apartment Model no sincroniza la comunicación COM, y los objetos COM deben sincronizarse entre ellos para protegerse desde multiples accesos. Este modelo de thread sólo está disponible en Win NT4 y Win 95 con DCOM 95.

Visual FoxPro y el MultiThread

Visual FoxPro 5.0 es single thread y sin embargo debe simular multithread. Por su parte VFP 6.0 ha sido dotado en sus objetos COM de la posibilidad de soportar el Thread Apartment Model y por lo tanto el soporte para Microsoft Transaction Server.

Si bien VFP 6.0 cumple las condiciones de los objetos COM que pueden pertenecer al Apartment Model Threaded COM y pueden ser hospedados dentro de una Transacción del MS Transaction Server, la concurrencia se mantiene como un problema.

El problema es la forma en la que está hecho el runtime de VFP. Mientras es posible cargar múltiples instancias de un objeto en el mismo proceso no es posible hacer que ambas instancias operen simultaneamente. Por ejemplo, si IIS carga dos nstancias de unobjeto desde dos accesos simultaneos a la misma página ASP uno se ejecutará después de otro – la segunda petición será puesta en cola. El siguiente escenario presenta un problema: Asumamos que el Metodo1 ejecuta una consulta que dura 15 secgundos y el Método2 ejecuta una consulta que dura 1 segundo. Si el Método1 se invoca antes de que se invoque el Método2 la llamada al método2 bloqueará durante 15 segundos la respuesta a la otra instancia. Sin concurrencia es extremadamente difícil construir aplicaciones escalables.

Los objetos de VB tampoco son multi-threaded, ellos lo que hacen es correr multiples instancias al mismo tiempo. Esto en realidad es un truco pues cada objeto obtiene su propia copia del runtime y así simula un entorno multi-threaded, pero no es multithread. Multi-thread implica una re-entrada de código: el mismo bloque de código físico corre simultaneamente. C/C++ permite correr código multi-threaded. Ironicamente, los objetos COM no trabajan como verdaderos objetos que pueden ser sometidos a Thread – preferiblmenete los objetos se deberían conformar al modelo de Apartamentos. VFP6 actualmente se conforma a este modelo pero tiene bloqueos internos para prevenir operaciones simultaneas de acceso a métodos y propiedades.

VB y VFP simulan el thread cargando en memoria multiples areas con su propio privado Thread Local Storage.

El problema con VFP es que hay muchas variables globales, que no se pueden aislar facilmente y almacenarlas en un almacen local por cada objeto. Por lo que puedo ver los bloqueos se necesitan para proteger que esas variables globales puedan ser accedidas desde multiples instancias. Las variables globales vienen a ser como variables de entorno como comandos set que regulan los buffers, etc... de la Base de Datos,etc.

Los servidores DLL (InProc) no son más rápidos que los servidores EXE (Out Proc) – es unicamente debido a las llamadas al Interfaz que son más rapidas. Para entendernos: el código corre a la misma velocidad – sólo cuando se pasan parametros el proceso se ralentiza mucho, mucho más con los servidores OutOfProc (tal como 500-1000 veces más lento) bajo condiciones ideales. El asunto es, que si tienes un procedimiento que ejecuta una consulta que toma 20 segundos en responder las diferencias entre los dos sistemas no serán notables ya sean InProc o OutOfProc. Pero si tienes una rutina que llama al servidor VFP en un pequeño loop que debe traerse un pequeño grupo de datos te darás cuenta de que la diferencia es de la noche al día.

El Apartment Model threading permite cargar múltiples componentes de tipo InProcess (DLL) de forma simultanea. Visual FoxPro puede manejar multiple simultaneous 'apartments' threads de tu objeto en memoria de forma simultanea (uno por cada cliente activo). el modelo de apartment garantiza que las llamadas se realizarán en el mismo thread que fueron creados con lo que se garantiza la seguridad para ejecutar las aplicaciones. La conversion de una herramienta tan compleja como VFP para que pueda ser integrada en un modelo de threads no es una tarea trivial y las mejoras que se han conseguido sobre la incapacidad de vFP 5.0 para ejecutar más de una instancia de un objeto COM en el mismo proceso. Desgraciadamente, múltiples instancias del mismo objeto en el mismo proceso (de la misma forma que IIS) no pueden operar simultaneamente ya que el primero bloquea al segundo. Aunque IIS pueda tener múltiples referencias de objetos, sólo puede correr un método por servidor al mismo tiempo. Puedes, sin embargo, tener dos servidores separados que corran dentro de IIS y hacer que funcionen simultaneamente.

Con Visual FoxPro 6.0 Service Pack 3 aparecer una nueva versión de la runtime que sí soporta la ejecución simultánea de métodos. Esta versión no ha sido liberada todavía.

En Resumen

Lo verdaderamente importate es:

  • 1.- Los Componentes ActiveX creados como EXE (con cualquier versión de Visual FoxPro) són más lentos en el paso de parámetro (se utilizan distrintos espacio de direcciones entre distintos procesos) y no pueden ejecutarse dentro de MTS
  • 2.- Los Componentes ActiveX creados como DLL con Visual FoxPro 5.0 no se puede utilizar dentro de MTS pues internamente no están contruidos siguendo el Apartament Model.
  • 3.- Los Componentes ActiveX creados como DLL con Visual FoxPro 6.0 se pueden ejecutar en MTS pero internamente se realiza un bloqueo de la runtime que impide ejecuciones simultáneas de métodos de distintos objetos.
  • 4.- Los Componentes ActiveX creados en Visual FoxPro 6.0 SP3 se pueden ejecutar en MTS y de forma simultánea pues existe una versión especial de la runtime de esta versión que permite la ejecución simultánea de objetos en distintos Thread.