Página 1 de 1

Re: Problema con apis de windows

Publicado: 16 Sep 2009, 09:03
por Ximorro
Sí, los hilos es algo así como la multitarea pero dentro de un programa. Multitarea es ejecutar varios programas diferentes a la vez, multihilo es que un programa concreto ejecute varias de sus partes a la vez ("a la vez" puede ser simulado, a menos que tengas realmente varios procesadores).

En el caso del AutoIt simplemente es que no está preparado para ser multihilo, así que es difícil saber qué puede estar pasando. Yo por lo pronto evitaría usar variables con el mismo nombre, aunque sean locales, pues no sabemos muy bien cómo gestiona AutoIt sus variables y a lo mejor comparten memoria si tienen el mismo nombre. Prueba a poner a $Num un nombre diferente en cada hilo a ver si ayuda algo...

Suerte, es un tema interesante pero me temo que sin soporte de los creadores de AutoIt es difícil, los problemas de sincronización de tareas son bastante peliagudos, poder registrar los hilos con la API está muy bien pero es el principio.

Al menos quizás sea posible mandar un hilo en paralelo de vez en cuando, para hacer tareas largas en segundo plano y seguir trabajando. En el ejemplo es que crea 4 de repente... (3 nuevos más el original). A ver si tengo tiempo y hago alguna prueba.

¡Suerte, ya nos contarás!

Re: Problema con apis de windows

Publicado: 16 Sep 2009, 09:36
por Ximorro
¿eres el Jonny de la consulta del teclado y los cambios de ventana? uau sí que estás activo ;-)

Pues me ha picado lo de los hilos y he hecho alguna prueba, efectivamente da muchos problemas, no parece que funcione bien. Desgraciadamente no entiendo demasiado la llamada a la dll, espero que ahí no haya fallos.

He creado hilos del tipo:
Func ThreadProc2($lpParam1)
Local $i1
For $i1 = 1 to 10
Sleep(Random(1,100,1))
Next
ConsoleWrite("Hilo 2 terminado" & @CRLF)
Return 0
EndFunc

Cada uno con sus variables propias, trabajan un tiempo aleatorio.

En el programa principal he puesto otros ConsoleWrite para ver qué se está haciendo (mejor que MsgBox para que no bloquee el proceso) pero efectivamente pasan cosas muy raras. Por ejemplo a veces se ejecuta un hilo varias veces y otros no:
Creando hilos...
¡Hilos creados! Esperando finalización...
Hilo 4 terminado
Hilo 4 terminado
!>09:32:24 AutoIT3.exe ended.rc:-1073741819

A veces acaba en error, a veces no. Muchas variantes pero creo que ninguna vez se ha ejecutado bien. No parece que se estén registrando bien las funciones, pero no sé si es culpa de la llamada o la dll o de autoit.

La verdad es que es un poco raro si funcionara, estas funciones no son código máquina, windows no las puede ejecutar directamente pues han de ser interpretadas por autoit. Para registrar los hilos estamos pasando punteros a funciones que para Windows no son ejecutables, han de ser interpretadas... no sé, no sé...

Por cierto, ¿nos podrías poner un enlace al foro inglés donde se hablaba de esto? a ver que comentan por allí...

Re: Problema con apis de windows

Publicado: 16 Sep 2009, 09:53
por Ximorro
Espero que no se me considere spammer por poner varios comentarios seguidos, es que voy probando cosas diferentes. La alternativa es editar el comentario anterior y hacer uno megalargo. Decidme lo que prefiráis, yo me adapto.

Pues bien, creo que el tema multihilo va a ser casi imposible. Efectivamente cuando se usan variables se hace un lío macabeo. Los diferentes hilos no acceden bien a sus variables. Falla incluso ejecutando un sólo hilo. Por ejemplo mi hilo es ahora así:
Func ThreadProc2($lpParam1)
Local $i1
For $i1 = 1 to 10
Sleep(Random(1,100,1))
ConsoleWrite("Hilo 2: " & $i1 & @CRLF)
Next
ConsoleWrite("Hilo 2 terminado" & @CRLF)
Return 0
EndFunc

Cuando no falla a mitad, que también ocurre bastante, hace cosas como:
Creando hilos...
Hilo 2: 1
Hilo 2: 3
Hilo 2: 4
Hilo 2: 5
Hilo 2: 6
Hilo 2: 7
Hilo 2: 8
Hilo 2: 9
Hilo 2: 10
Hilo 2 terminado
Hilo 2: 11

Fijáos que se ha dejado el 2... ¡y a ha llegado a 11! Cosa imposible, pues el bucle llega hasta 10. Es como si al salir del bucle (donde $i1 efectivamente vale 11) se acuerda de que tiene que imprimir su valor, y lo hace con retraso. ¡De hecho ese mensaje lo imprime DESPUÉS de "Hilo 2 terminado"!.

Muchas veces hace:
Creando hilos...
Hilo 2: 2
Hilo 2: 2

¡Y acaba sin error! como si todo hubiera ido bien, pero no ha ido nada bien.

Creo que va a ser imposible, al menos de esta manera...

Re: Problema con apis de windows

Publicado: 16 Sep 2009, 17:16
por Jonny
Hola

sí, el mismo jejejeje.

El código lo saqué de
http://www.autoitscript.com/forum/index ... ntry499037

No entiendo por que dices que sería raro que funcionara, por no ser código máquina... Si lo compilas ya no ha de ser interpretado por autoit y el resultado sería el mismo.

Es curioso, porque yo no recuerdo que tubiera ese tipo de problemas (hace ya algún tiempo que puse éste post), sinó que el problema en mi caso, surgía al incluir funciones gui en el programa.
Las pruebas prébias que hice anteriormente a incluir guis, parecían ir bien. Los códigos de ejemplo que hice eran algo parecido al original y a lo que has hecho tú pero en vez de con For, lo hice con While.

¿Dices que el problema podía ser las variables?
Si Autoit puede hacerse un taco con las variables locales ¿Serviría como chapuza hacerlas globales?

Es cierto que autoit no está preparado para el multihilo (lástima) pero yo creo que ese no es el problema. En teoría, con éste código es la dll, la encargada de manejarlo, supuestamente Autoit se comporta normalmente.
Prueba de ello, almenos muy parecido, es la librería Timers.au3, que en cierta manera se comporta como el multihilo, pero trabaja con otra api de Windows.
Como dices, el problema tiene que estar en la dll, o más bien en la llamada, la forma de registrar las funciones ... por ahí por ahí. Pero como dige en otros posts, no tengo ni idea de apis de Windows y menos tan complicadas de tratar.

La verdad, es que sería la leche que ésto llegara a funcionar jeje. Claro, que faltaría poder implementar las demás funciones de threads de que dispone la api de Windows. ThreadStop, etc, para tener control total sobre los hilos de una aplicación. Lo suyo sería entonces, una UDF para ello.

A ver si primero conseguimos que esto funcione como debe...

Salu2!

Re: Problema con apis de windows

Publicado: 17 Sep 2009, 09:33
por Ximorro
Hola Jonny, ese enlace que pones habla de multi-threading pero no es exactamente el código que pones.

Me temo que AutoIt no es "compilado", si por ello entendemos la generación de código máquina. Aquí compilar es pasar a una especie de lenguaje intermedio, o quizás es sólo el original encriptado con pocos cambios. Resulta que cuando hacen un exe ahí meten un pequeño intérprete, por eso aunque hagas un programa que sólo haga "$a = 2" el exe ocupa 600kb (sin usar UPX). Está interpretado, lo que es código máquina es el intérprete, no nuestros programas en AutoIt.

Cuando ejecutas directamente un au3, está usando el intérprete AutoIt3.exe (o AutoIt3_x64.exe para 64bits).

Y por todo eso el lenguajes es como es: sin datos tipados (en una variable puedes meter enteros, reales, cadenas...), sin estructuras, no es muy rápido (p.e. cálculos matemáticos). En definitiva lo mantienen lo más simple posible para que el intérprete sea pequeño, y así generar exe's pequeños.

Se me hace raro lo de registrar en Windows como hilo una función interpretada, pero bueno, llamarla la llama, así que de alguna manera el intérprete se mete por medio.

He estado buscando cosas sobre esto en el foro inglés, y no parece que vaya a ser posible, los desarrolladores hablan precisamente por ejemplo del acceso a las variabes, el espacio de memoria donde están no está protegido para uso multihilo y varios hilos accediendo a la vez pueden hacer malezas, aunque no usen la misma variable. Y ese sólo es un ejemplo, dicen montones de veces que AutoIt no está diseñado para multihilo y que en esta versión 3 no se puede, que "a lo mejor" para la 4, pero eso volviendo a crear AutoIt desde cero...

Si no está diseñado para multihilo por mucho que uses la API de Windows creo que esos hilos se comportarán erróneamente porque internamente lo que los ejecuta (autoit) no está preparado para manejarlos de esa manera.

Otra cosa es que AutoIt use multihilo de vez en cuando, pero es que AutoIt no está hecho en AutoIt, sino en C++ ¡que sí es totalmente compilado y puede programarse con varios hilos mucho más fácilmente! Un caso clarísimo es InetGet, que puede ponerse a descargar en modo "background", o sea, segundo plano.

El caso Timer que comentas quizás se pueda considerar algo parecido, pero es que un timer no hace nada, sólo espera cierto tiempo y te notifica cuando ese tiempo ha pasado. Y autoIt sí está programado para recibir esas notificaciones de Windows, pero no está ejecutando varias cosas a la vez, si el timer tiene una función asociada eso se ejecuta al acabar el timer INTERRUMPIENDO el programa original, no es exactamente multihilo.

Y que conste que no digo que un lenguaje tenga que ser compilado a código máquina para poder tener multi-hilo, pero me temo que el lenguaje que sea debe estar diseñado para ello. AutoIt podría ser multi-hilo, pero sus "interioridades" deberían ser reprogramadas con eso en mente, y debería ser el propio lenguaje el que dé los mecanismos para multi-hilo, o sea, que diera funciones CreateThread, RunThread, StopThread y compañía.

Sigue investigando que siempre se aprende, pero si te miras bien los foros ingleses verás que está chungo chungo.

En este post en concreto los padres de AutoIt participan muy activamente, y lo ponen muy muy negro. Si puedes con el inglés te recomiendo leértelo, si no podría mirar de traducirte alguna cosa...

Ciao

Re: Problema con apis de windows

Publicado: 17 Sep 2009, 11:22
por Chefito
Estoy totalmente deacuerdo contigo. AutoIt no está preparado para programación multihilo.
No es porque sea un lenguaje interpretado, sino porque como bien dices, no ha sido diseñado pensado para eso, y por eso al intentar utilizar estos métodos te pueden dar resultados extraños y hacer una aplicación inestable.
Hay lenguajes interpretados que hacen multihilo muy muy bien (java, .net, etc). Incluso hay lenguajes interpretados muy muy muy rápidos (.net).

No he intentado el multihilo con apis por todo lo que dicen. Quien sabe, lo mismo algún día me animo y lo intento, pero en principio no tengo esa intención. Por ahora no lo necesito para nada, y meterse con esas apis es la muerte :smt005 :smt021 :smt021 .

Saludos.

Re: Problema con apis de windows

Publicado: 17 Sep 2009, 17:06
por Jonny
Hola

No....
No me llevo muy bien con el inglés. y mucho menos a esos niveles...
Por eso me pierdo tantas cosas interesantes de autoit, como lo que me has contado.

A ver si lo he entendido bien.
¿Quieres decir, que en realidad cuando compilamos un programa en Autoit no se genera un programa compilado, tal como C++, vb etc?
Que en realidad es como si estubiéramos ejecutan´do el código fuente (el .au3)?
Yo pensaba, que ocupaba tanto un programa que por ejemplo únicamente contubiera un msgbox, por que incluiría librerías o algo así... pero no imaginaba que el .exe fuera interpretado :P.

Bueno, lo de que Autoit no está preparado para ser multihilo lo he oido siempre, pero pensé que con esta api podría hacerse algo, pero veo que no. habrá que seguir tirando de timers jeje. Que por cierto, ¿Dices que esperan a realizar la acción que sea para continuar ejecutándose?
los que incluye la última versión de autoit, no se comportan así. Incluso si hacemos un timer que se ejecute cada 0 msg (para simular lo más real posible el multihilo) y en el timer ponemos únicamente un Msgbox(), éste se ejecuta indefinidamente, aún sin pulsar en "Aceptar" en la ventana que aparece lanzada por el Msgbox().
Poreso comparé los timers con los threads. Si quieres probarlo y no quieres tener que reiniciar el pc, prueba con un tiempo mayor a 0 msg, igualmente se te ejecutará el msgbox indefinidamente, aunque no quites el primero, que es como teóricamente debería funcionar ¿no?
Almenos, una librería que tube de timers hace ya bastante tiempo (aún conserbo por algún sitio del disco duro) funcionaba así. se ejecutaba el timer y cuadno terminaba volvía a ejecutarse transcurrido el tiempo indicado. Si había una función bloqueadora como el msgbox() (Te lo puse como ejemplo precisamente por eso) el timer digamos, que se pausaba hasta que no desapareciera esa ventana.

Salu2!

Re: Problema con apis de windows

Publicado: 18 Sep 2009, 09:48
por Ximorro
Jonny escribió:Hola
¿Quieres decir, que en realidad cuando compilamos un programa en Autoit no se genera un programa compilado, tal como C++, vb etc?
Que en realidad es como si estubiéramos ejecutan´do el código fuente (el .au3)?
Yo pensaba, que ocupaba tanto un programa que por ejemplo únicamente contubiera un msgbox, por que incluiría librerías o algo así... pero no imaginaba que el .exe fuera interpretado :P.
Efectivamente, es intérpretado, voy a traducir un par de cosas de la ayuda:
-
Los scripts pueden ser compilados con extensión .a3x . Deben ser ejecutados con "AutoIt.exe filename.a3x". El .a3x contiene el propio script con todos los #include referenciados más los ficheros incluidos con FileInstall. Este formato permite distribuir archivos más pequeños pues ellos no incluyen AutoIt3.exe en cada script compilado. Necesitas tenerlo accesible en la máquina, pero sólo el archivo AutoIt3.exe.
-

Es decir, los scripts compilados incluyen AutoIt3.exe dentro de ellos, es lo que realmente ejecuta el script, AutoIt3.exe es nada menos que el intérprete, lo que usas para ejecutar los au3.
Las librerías que incluye son las propias de autoit (las de los #include<fichero.au3>). Como librerías usa extensamente las propias de Windows, no se le pueden linkar librerías compiladas a código máquina.

Otra nota:
"el script a ser compilado debe estar libre de errores de sintaxis pues el compilador no chequeará la sintaxis". (¿te suena esto? ¿no tenías problemas con las compilaciones que te pasaban errores de Autoit? pues aquí lo decían...)
Sencillamente, es imposible compilar a código máquina sin chequear sintaxis, si la sintaxis no es correcta a ver qué compilas. Si es interpretado "traga" mucho más fácilmente, aunque cascará en ejecución.

En el foro en inglés, más de una vez ante peticiones de nuevas funcionalidades de AutoIT, las han rechazado "porque harían el intérprete muy grande, y por lo tanto los ejecutables". Así que el intérprete es claramente necesario para ejecutar los scripts, incluso los compilados.
Jonny escribió: Bueno, lo de que Autoit no está preparado para ser multihilo lo he oido siempre, pero pensé que con esta api podría hacerse algo, pero veo que no. habrá que seguir tirando de timers jeje. Que por cierto, ¿Dices que esperan a realizar la acción que sea para continuar ejecutándose?
No, no quería decir que el timer se esperara, sino simplemente que aunque lo parezca AutoIt no está ejecutando varias cosas a la vez en varios procesadores o en multithreading simulado. El timer efectivamente no espera a que el código pare, el timer interrumpe el código en ejecución y ejecuta su función asociada, cuando esa función acaba vuelve al código principal de autoit donde estuviera antes.
Es una interrupción, pausando lo que se está haciendo, y reanudándolo después de que la función asociada al timer finaliza.
El timer en sí si es algo en paralelo, pero es tremendamente simple y se deja a Windows, básicamente es un proceso que está esperando el tiempo que le dices sin hacer nada, cuando pasa ese tiempo te manda un mensaje, AutoIt recoge ese mensaje y es entonces cuando ejecuta la función asociada si la hay.

Te hablo de la librería Timers.au3 que viene con AutoIT, pero sospecho que las demás harán algo parecido, no creo que ninguna haga multihilo, siendo que en el foro en inglés lo están esperando como locos. Ya habrían dicho que sí hay librerías en multihilo, y no es así

Dicho esto, pues sí, a base de timers puedes simular ejecución paralela, porque con tiempos pequeños al usuario le parecerá que las dos tareas se están ejecutando a la vez, pero en realidad las dos van más lentas porque no están usando las ventajas de multiproceso del hardware, que aunque no tengas varios procesadores sí puedes tener varios núcleos o multithreading por hardware. Los timers no usan eso, intercalan ejecuciones de tareas diferentes, pero una detrás de la otra...

Así que si buscas tareas en ejecución simultánea a nivel hardware (para que la ejecución paralela sea eficiente) pues me temo que no... PERO si lo que buscas es simular multihilo, para que el usuario perciba la ejecución simultánea de varias tareas, a base de timers, ¡pues sí!, eso sí te lo puedes montar.

¡Saludos!

Re: Problema con apis de windows

Publicado: 18 Sep 2009, 11:00
por Ximorro
Por cierto, comentario un poco al margen, VB tradicionalmente siempre ha sido interpretado, por eso hacía falta las VBRUNxxx.dll, que eran el intérprete. Ahora con .NET la cosa ha cambiado, pero sigue sin ser puramente código máquina, todos los lenguajes de .NET se compilan a un lenguaje intermedio común (por eso da igual qué lenguaje uses, las prestaciones son las mismas). Ese lenguaje intermedio es compilado a código máquina en ejecución, muy parecido a lo que se hace con Java. Java y .Net son interpretados, pero podríamos decir que son intérpretes de segunda generación, muy muy eficientes.

AutoIt nunca a tenido tales pretensiones, es un lenguaje de scripting, pensado para automatizar tareas en Windows, facilitar acceso a las interioridades de Windows y las aplicaciones que corren sobre él, y con la idea de poder distribuir sencillamente ejecutables autónomos pequeños. Lo que hace lo hace bien, si queremos por ejemplo cálculos matemáticos a la velocidad de la luz por ahora tendremos que usar otros lenguajes.

Por eso de hacerlo simple no tenemos multihilo, ni estructuras de datos como nos gustaría (y menos mal que tenemos matrices), pero por ejemplo da gusto poder hacer una llamada a una API de Windows... ¡escribiendo dos líneas de código!. Y encima te hace un ejecutable autónomo que puedes pasar sin adjuntar veinte DLLs o instalar un runtime (como con .NET o Java).

Por ejemplo, en un programita que hice para comprobar números primos, AutoIt tardaba 46.6 segs en ver que 9007199254740881 es primo. En Java exactamente el mismo método me lo ejecuta en 0.57 segs... casi 100 veces más rápido.

Pero por otro lado en AutoIt puedo plantar con cierta facilidad un nuevo submenú en el menú del Notepad (¡una aplicación que no es mía y de la que no tengo ni los fuentes!) que sea "Enviar a Scite", que sea capaz de leer el texto que tiene abierto el Notepad y copiármelo en una nueva ventana de Scite. Hacer eso en Java, si es que se puede, tiene que ser de pesadilla. Así que a cada uno lo suyo. AutoIt está muy bien aunque no tenga ejecución multihilo, de todas maneras aunque interesante, eso tampoco sería lo primero en mi lista de peticiones...

¡Bien por AutoIt!

Re: Problema con apis de windows

Publicado: 18 Sep 2009, 12:19
por Jonny
Hola

Ahora entiendo lo de los errores en los porgramas compilados... jeje. Claro, esto no lo sabía...

Gracias por la aclaración de los timers, porque nunca entendí estos timers que incluye ahora autoit... siempre me parecieron un tanto extraños, por eso, porque parecía multihilo. La verdad, es que debe de haber diferencia (la hay) pero hay que saber mucho del tema o hacer muchas pruebas realmente para verlas...
Como lo que importa en el fondo es el resultado final de la aplicación y el usuario en principio no va a notar si son timers o multihilo... Pueden aprovecharse para ir tirando jeje.
Pues, me uno a la comunidad inglesa, yo también estoy deseando que salga una versión de Autoit que soporte el multihilo real, para mí es una de las pocas cosas que le faltan a éste lenguaje (Seguro que técnicamente le faltan varias) pero para mí eso y poder compilar para otras plataformas, sería la leche.
Y si nos ponemos, que Autoit permitiera crear dll's, también estaría bien jejeje.
(Por pedir que no quede)

Salu2!

Re: Problema con apis de windows

Publicado: 18 Sep 2009, 13:47
por Ximorro
Pues nada, cuando tengas un simulador de miltihilo nos lo pones :smt098

Ya digo que si AutoIt tuviera multihilo no me iba a quejar precisamente, pero preferiría antes otras cosas, como estructuras de datos más complejas, tipo registros (los struct de C), por no decir objetos, o estructuras dinámicas para hacer pilas, listas, etc...

Además te advierto que programar en multihilo puede ser una pesadilla. Hacer rutinas totalmente independientes no es problema pero cuando quieres que cooperen entre ellas puedes armar un buen cacao. Java por ejemplo, que sí tiene multihilo, a veces tiene dos versiones para un objeto, según si se puede usar en multihilo o no, porque la versión multihilo hay que programarla especialmente para ello, y si no vas a usar hilos mejor coges la otra porque te irá más rápida... Vaya, que no es fácil programar para multihilo.

Lo de compilar para otras plataformas sí lo puedes olvidar, eso sí está claro. AutoIt está estrechamente ligado a Windows, su mayor potencial es el acceso a los controles Windows, la API del sistema, el registro... Pasar todo eso a otro S.O. sería como empezar a hacer un AutoIT desde cero...
Precisamente el hecho de hacer maravillas con un intérprete de 600kb (sin comprimir) es porque delega montones de tareas a base de llamadas a las dll de Windows. En otros S.O. como no están esas DLL ponte a buscar cosas equivalentes, y si no están toca ponerte a programarlas tú...

Lo de las dll igual sí es posible... metiendo el intérprete en la dll :smt002

Re: Problema con apis de windows

Publicado: 18 Sep 2009, 16:27
por Jonny
Hola

Ya, ya me imagino, que programar en multihilo no tiene que ser hacer un par de timers y listo... No lo he hecho nunca (en otros lenguajes) pero me supongo lo chungo que tiene que ser.

Bueno, lo de compilar para otras plataformas ... Me gustaría, por aquello de que Autoit es el lenguaje que más domino y podría exportar aplicaciones a otros sistemas operativos, pero realmente no cuento con ello precisamente por la complegidad que supondría desarrollar una versión de Autoit que lo permitiera, además de que por supuesto ello imagino que también complicaría la programación de scripts (contrario a la filosofía de Autoit) ¿No?.
Le doy más prioridad a lo de poder compilar dll's...

Salu2!