Multihilo en autoit

Tus preguntas. Algoritmos o Grupos de Comandos formando Programas Escripts.
Responder
Avatar de Usuario
chekok
Hacker del Foro
Mensajes: 111
Registrado: 16 Sep 2011, 11:50
Ubicación: Valencia / España
Contactar:

Multihilo en autoit

Mensaje por chekok »

Hola, he repasado la ayuda y el foro y no he encontrado nada al respecto.

El problema es que ayer me puse a hacer una nueva aplicación y necesito que desde el mismo script ejecute 2 funciones pero cada una como proceso independiente.
Pensé en hacer 2 .exe independientes y desde el primero llamar al segundo exe, así funciona, pero no me vale por otros motivos.
La cuestión sería que desde un solo exe, poder crear 2 procesos independientes, pero que la programación esté en un solo script.
No se si me he explicado bien.
La aplicación es un reproductor de TV TDT que recoge la imagen de una capturadora USB. El problema es que si muestro por ejemplo el mando virtual por encima de la imagen, la imagen se para mientras muevo esa ventana al estar corriendo en el mismo proceso. Si los corro como exes separados, el problema desaparece, pero no me parece lógico tener un exe para el reproductor y otro exe para el mando flotante, además que no me valdría así para otras funcionalidades que llevo pensadas en meter.

Confío en que me podais hechar una mano. Para más info la imagen la capturo con avicap32.dll de Windows (existe en todos los sistemas windows que he visto, desde XP hasta W8).

Gracias.
La vida es larga y dura.
Avatar de Usuario
chekok
Hacker del Foro
Mensajes: 111
Registrado: 16 Sep 2011, 11:50
Ubicación: Valencia / España
Contactar:

Re: Multihilo en autoit

Mensaje por chekok »

Me he precipitado, perdonad mi impaciencia.

Ya lo he solucionado, está en el foro en inglés.

Para el que lo necesite este es el hilo:
http://www.autoitscript.com/forum/topi ... s-helper/

Gracias.
La vida es larga y dura.
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Multihilo en autoit

Mensaje por Jonny »

¿Que has encontrado en esa página sobre el multihilo en AutoIt?.

Si no ha cambiado nada, que no lo creo, en AutoIt no existe el multihilo.
Siacaso puedes simularlo. Puedes hacerlo de varias formas, he visto de todo para emular el multihilo, y ninguna opción me ha gustado. Por supuesto, la forma que decías de ejecutar dos .exe's a la vez también la usan bastante, y no solo en software hecho en AutoIt, sino en muchos programas hechos en otros lenguajes.
A mi no es que sea una práctica que me guste, pero si no hay inconveniente por el desarrollador es una opción.

Como no es tu caso, puedes intentarlo de otras formas. La mejor diría yo, es que utilices las funciones _Timer() de la librería Timers.au3.

Dicen que no es lo mismo, y es cierto, pues un timer no es lo mismo que un thread; pero este tema lo he investigado muchísimo desde que toco Autoit, y no veo ninguna diferencia importante entre las apis thread de Windows y las apis timer de este (las que usa la librería Timers.au3). Incluso con funciones bloqueadoras como msgbox(), puedes ejecutar dos timers a la vez. Así, que la diferencia entre estas apis y las de threads es para mi, símplemente técnica, porque como digo en la práctica funciona igual. Para que los timers parezcan hilos, debes ejecutarlos cada 0 milisegundos, o, si no quieres sobrecargar tanto el procesador puedes darle un tiempo de pausa entre ejecución y ejecución: 5 milisegundos por ejemplo, y aún así no se nota la diferencia pero dejas trabajar más desahogado al procesador.

Si te gusta hacerlo muy muy profesional :), tienes las apis thread de Windows, que alguien ha intentado usar con Autoit en el foro Inglés (en este también hay posts dónde hemos hablado de ellas), pero sin mucho acierto. Es cierto que puede llegarse a hacer que se ejecuten dos hilos a la vez, pero a la que pongas bucles con según qué, el ordenador se vuelve loco y es un desastre.

A mi se me ocurrió hace tiempo una forma de comunicar AutoIt con las apis thread de Windows, pero como no tengo mucho tiempo para los experimentos nunca lo acabo de hacer. Además, habría que programar en C++ y no lo domino tan bien como AutoIt.

Si dominas C++, las APIS de Windows y tienes ganas, te doy una pista:

Puedes hacer una Dll, que se comunique con las Apis thread, que es lo que no puede (por algún extraño motivo) hacer AutoIt. Y a su vez, esta DLL, podría comunicarse con AutoIt para invocar funciones Callback cuando recibiera una llamada a un callback de la dll (no se si me he explicado del todo bien) :).
Si te interesa hacer esto y no me has entendido, dímelo y te lo explico con más detalle :P.

No se que les costaría a los desarrolladores de AutoIt hacer que las Apis Thread de Windows funcionaran bien con este, ya que no quieren implementar el multihilo...

Algún día, quizá haga esa dll, que según la tengo pensada debería funcionar. Pero, aún no se me ha ocurrido como hacer que no tenga alguna que otra limitación, como por ejemplo el número de hilos que pudiera manejar (hacer que no tuviera límite). No debe ser muy complicado, pero al no dominar al cien por cien C++ no se me ocurre la manera :).

Salu2!
Avatar de Usuario
chekok
Hacker del Foro
Mensajes: 111
Registrado: 16 Sep 2011, 11:50
Ubicación: Valencia / España
Contactar:

Re: Multihilo en autoit

Mensaje por chekok »

Jonny, gracias por tus aclaraciones.

En mi caso, la necesidad era poder ejecutar como un proceso distinto cada función de mi script, lo cual a quedado solucionado con lo que he visto en el hilo del foro en inglés.

Sobre la pista que me has dado sobre hacer una dll con c++, queda muy muy lejos de mis conocimientos, ya que el primer contacto que he tenido con la programación en windows hecha por mí mismo ha sido con autoit y lo conozco desde hace 2 o 3 meses (suelo hacer cosillas con php relacionadas con el comercio online, pero son tan básicas que no lo considero programar).

Ahora ya tengo más claros los conceptos de proceso e hilo (gracias Jonny). Tendría que haber llamado al tema "Multiproceso en autoit" en lugar de "Multihilo en autoit".
La vida es larga y dura.
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Multihilo en autoit

Mensaje por Jonny »

Ah, bueno, entonces ahí queda la idea para si alguien que controle C++ y le apetece... :)

Quizá sí, porque en realidad no es lo mismo un hilo que un proceso, creo. De hecho, para manejar procesos AutoIt tiene alguna que otra función, e incluso hay una librería si mal no recuerdo. Y es que, diría que Windows tiene apis para threads, timers y procesos...

De todas formas, si lo has arreglado nada. Pero si no, creo que lo que buscabas era hacer dos cosas de forma simultánea en un mismo proceso. Pues para eso, lo mejor en AutoIt son los timers, pero los que se gestionan con la librería que incluye AutoIt, porque he visto en el foro inglés que hay otras librerías; de hecho, durante un tiempo hace ya bastante (aún AutoIt no incluía esa UDF) usé una librería que gestionaba timers, pero no era tan buena como esta, pues con un simple MsgBox() se te bloqueaba el programa. Y es que, los timers los hacían con las funciones... Adlib().

Salu2!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Multihilo en autoit

Mensaje por Ximorro »

Autoit no soporta programación multihilo porque el intérprete no se ha programado para que lo soporte, así que efectivamente lo único que se puede hacer es simularlo, tal como comenta Jonny, ya sea con temporizadores (con librería timers, la API de timers o las funciones Adlib, en realidad todo acaba usando lo mismo) o si no hay más remedio con un programa que lance varios exes, que pueden ser él mismo. Es más cutre pero más fácil.
No se que les costaría a los desarrolladores de AutoIt hacer que las Apis Thread de Windows funcionaran bien con este, ya que no quieren implementar el multihilo...
Pues es que no es trivial, la programación concurrente no es tan sencilla, una cosa es ejecutar dos procesos distintos que no tienen nada que ver entre sí, otra es ejecutar hilos de un mismo proceso, compartiendo variables y otros recursos...
Tal como lo discutían creo que sí lo han evaluado, pero su objetivo principal siempre ha sido mantener el intérprete pequeño (cada exe de AutoIt que hacemos lleva el intérprete consigo) y la programación multihilo pues lo hará crecer y consideran que no es algo tan vital. Mala suerte.

chekok, ¿has probado a usar gestión de eventos con el modo OnEvent, en vez de usar un bucle en el que miras continuamente qué evento ha llegado con GuiGetMsg se asigna una función a cada evento y te olvidas. Luego si acaso lo pruebo y te digo, quizás lo de mover la ventana siga siendo bloqueante. Me suena haber visto una manera de mover ventanas que no las bloqueaba, pero igual era con GDI que al estar dibujando de otra manera no le afectaba. Lo miraré también.

Es decir, el problema no es exactamente cómo hacerlo multihilo, tu problema es mover la ventana sin que quede paralizada la otra, si se encuentra otra solución también vale ¿no?

Eso sí, si lo haces con el sistema ese simulando multihilo nos pones algún ejemplo para compartirlo con la comunidad.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Multihilo en autoit

Mensaje por Ximorro »

Pues no, no lo consigo, el modo OnEvent sigue bloqueando cuando mueves la ventana.
Y moviendo a base de registrar mensajes tampoco es...

Pues haciendo pruebas con GDI recuerdo haber tenido una ventana que seguía actualizándose cuando la movía, pero igual es más cosa de la forma de dibujar con GDI+...
Mala suerte, ya nos contarás lo de los hilos.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Multihilo en autoit

Mensaje por Jonny »

Las funciones Adlib, no las he usado nunca. Realmente no se que es eso de "adlib", y no me gustan porque bloquean el programa (almenos cuando las probé hace bastante tiempo).

Ahora que lo mencionas.

Nunca me he puesto a tocar eso de los procesos, pero se que hay apis, y hasta una UDF en AutoIt para manejarlos.
¿Soportaría el intérprete de AutoIt la ejecución de varios procesos paralelos?.

Como dije, la diferencia entre un timer y un thread, según el funcionamiento de las apis de Windows, para mi es casi técnico, más que otra cosa. Y pensando en los procesos, los veo exactamente igual...
¿Que diferencia hay entre ejecutar dos procesos, dos threads o dos timers?. Las tres cosas, se ejecutarían a la vez ¿no?.

Alguna diferencia más debe haber entre un thread y un timer, cuando funcionando aparentemente igual, el intérprete de AutoIt soporta timers, pero no threads... Seguro que es cualquier cosa mínima de soporte de unas apis y otras, porque ¿sinceramente crees que aumentaría tanto de tamaño el intérprete de AutoIt si soportara el multihilo?. Yo creo que no.

Y seguramente, aunque no sea algo imprescindible (para programas medianamente complejos casi lo es) para mi, seguro que mucha gente (entre los que me incluyo) preferirían que el intérprete ocupara unas pocas kbs más, pero soportara el multihilo, que no como es actualmente. Pero es cierto que no deben darle demasiada importancia, sabiendo que hay formas de emularlo y que tampoco es necesario para hacer un programa.

AutoIt para mi es el mejor lenguaje (será porque lo domino :)), pero en mi opinión tendría que evolucionar un poco su filosofía, para poder extenderse más aún.

Si buscas por Google, ves que los pocos sitios dónde hablan de AutoIt (hablo de resultados en español) se refieren a él mayormente, como un sistema para hacer tareas automatizadas... y yo sin embargo, en el punto en el que está, lo veo como un lenguaje de programación, más que como un sistema para automatizar tareas :).

En fin, seguiremos tirando de timers mientras no se decidan a hacer que el intérprete soporte el multihilo :)

Para hacer que la ventana se actualice y se mueva a la vez, yo lo haría tirando de timers, es lo más sencillo.

Por cierto: No he tocado la programación multihilo en otros lenguajes, pero no debe ser tan difícil ¿no?.

Lo poco que pude hacer funcionar las apis thread de Windows en AutoIt, parecía que podía compartirse una variable global entre dos funciones de hilos distintos. Quizá, en la programación multihilo, haya que tirar más de mensajes entre funciones, objetos ...

Eso me recuerda a la POO, una forma distinta de pensar a la hora de picar código :). Quizá eso sea lo difícil?.

Salu2!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Multihilo en autoit

Mensaje por Ximorro »

¿¿Qué no sabes "que es eso del AdLib"??

Pues antes de meterte con hilos y librerías externas de timers es lo que tenías que haber usado.
Es ni más ni menos el mecanismo que ofrece AutoIT para ejecutar una función (o varias) en determinados intervalos de tiempo, vaya, como un timer, en realidad es un timer integrado en AutoIt.

Si te bloqueaba es porque la función tardaba más tiempo que el timer, si la ejecutas cada 20ms y tarda en ejecutarse 50ms, lógicamente queda bloqueado porque no le da tiempo. Yo lo he usado muchas veces y nunca he tenido problemas.

Un timer y un thread son cosas diferentes. Un timer se implementa en un thread separado, precisamente para que no sea bloqueante, pero un thread no es un timer. Es como decir que la diferencia entre un programa y el NotePad es técnica. Pues no exactamente, el NotePad es un programa, pero un programa no es el notepad, es algo más genérico...

Un hilo tampoco es un proceso.
Un proceso puede tener varios hilos (líneas de ejecución paralelas) que comparten los mismos recursos del proceso. Esa compartición es precisamente lo más complicado de hacer un programa multihilo, evitar condiciones de carrera y bloqueo de recursos puede ser una pesadilla. Yo he hecho alguna cosa (poco) en Java, y te aseguro que preparar un objeto para que sea accesible concurrentemente tiene su gracia...
¿sinceramente crees que aumentaría tanto de tamaño el intérprete de AutoIt si soportara el multihilo?. Yo creo que no.
¡Yo creo que bastante!. Y sería complicado de programar.

Cógete Java, programa algún objeto multihilo, y cuando sientas temor al ver la palabra synchronized ya sabes de qué va esto y puedes vover a este... ¿hilo? ;-) a seguir discutiendo.
Mejor no hagas estos comentarios en el foro inglés porque Valik irá a buscarte a tu casa :smt005

Multihilo tampoco está ligado a programación orientada a objetos. Lo primero es una capacidad del S.O. (y del hardware) de mantener varias líneas de ejecución para un mismo proceso, lo segundo es una manera de escribir programas.
Si el S.O. admite multihilo da igual que eso lo programes en OO, en un lenguaje estructurado iterativo, o en ensamblador. Al final todo es código máquina, que es lo que realmente ejecuta el procesador.

Ya que has manejado tanto lo de la librería de los timers ¿por qué no haces un miniprograma que cree dos GUIs, en cada uno simplemente que actualice una etiqueta con un timer? (un timer para cada ventana, para que vayan por serparado, por ejemplo que ponga la hora, o incremente un simple contador), y así vemos si la cosa no se bloquea al mover la ventana.
Lo probaré con Adlib, pero no creo que funcione al estar tan integrado en AutoIt probablemente la congelación del script bloquee sus timers internos, pero tú hazlo con esas librerías que has manejado que si hacen timers externos al proceso de tu programa puede que funcione...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
BasicOs
Site Admin
Mensajes: 2085
Registrado: 21 Nov 2006, 19:24
Ubicación: El Internet - (Canarias, España)
Contactar:

Re: Multihilo en autoit

Mensaje por BasicOs »

Tambien puedes simularlo que todo es relativo, haces un función como coordinador y vas enviando trabajos a cada subfunción por cada parte del tiempo, el windows tambien lo hacía así y era una multitarea simulada, al final da igual, mientras tengas un buen procesador.... Aunque hay casos más específicos,

Func PilaMulti()
Hazfuncion1() ; SI NO PUEDES SALIR DE LA FUNCIÓN Y DEJAR LA TAREA EN ESPERA PUEDES USAR UN EJECUTABLE HAZFUNCION.EXE
Hazfuncion2()
Hazfuncion3)
Endfunc

; ejemplo de subfunción
Func Hazfuncion()
For $i=1 to 30 (Hacer 30 subveces la tarea o se puede controlar por un timer o con variables de tiempo, ... o por volumen según se quiera controlar las tareitas
Haz una tareita o parte de la tarea
Next
Return ; devuelve el control a la func principal
End Func

:smt033 :smt033 :smt033

Claro suponiendo que cada función haga cosas que se puedan parar para devolver el control a la función principal,(el Autoit va ejecutando por orden) si no puedes usar ejecutables del windows con RUN,
Salu22:)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Multihilo en autoit

Mensaje por Chefito »

Yo, hace unos meses, hice pruebas con el tema de simulación de multihilo con timers, tanto adlib como _timer_settimer (api). Pienso que adlibregister tiene que llamar a esta api de alguna manera, seguramente con algún parámetro cambiado.

Bueno, pues mi conclusión fue que adlib interfería menos en el movimiento de la ventana (creo que lo podía poner a 1 milisg. sin problemas). El movimiento era suabe. En cambio, con _timer_settimer, si lo bajaba mucho, el movimiento de la ventana al arrastrarla era algo brusco (iba a trompicones). Creo que tenía suabidad con unos 50 milisg. Por supuesto, en ambos casos seguía ejecutándose el código de las funciones aunque movieses la ventana.

Supongo que dependerá de varios factores, como de la velocidad de la máquina, s.o., el código que lleve dentro la función, etc.

Yo lo probé en mi portatil que es bastante rápido y tiene w7 home 64 bits.

El otro efecto que ya comenté en una ocasión en este foro, es como dice Jonny, con _timer_settimer no se suele parar el código que llama esta función al saltar por ejemplo un msgbox o ventana similar. En cambio, con adlib sí. Porque he dicho antes que "no se suele...."?, porque hace poco, en otro código, probé lo mismo y sí se me paró :smt017 . Cosas raras que pasan cuando intentas hacer cosas raras en los códigos :smt005 .

Podeis comprobar estos efectos facilmente.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Multihilo en autoit

Mensaje por Jonny »

Lo de que la ventana se moviera a trompicones no lo se, porque exactamente eso no lo había probado. Yo decía que usando timers, el programa no se bloqueaba como sí seguramente podía pasar con las funciones adlib.

En cualquier caso, son muy curiosas las apis timer. Probad esto y veréis, que los timers no solo no esperan terminar la ejecución del callback al que llaman para seguir ejecutándose, sino que si hay más de un timer cada uno va a su bola, y no se preocupan unos de los otros, ni de terminar de ejecutarse ellos mismos :P (por eso compararlos tanto con las apis thread aunque no sean lo mismo :)):

Código: Seleccionar todo

#Include <GUIConstants.au3>
#Include <Timers.au3>

Global $Timer1, $Timer2, $WinTimer, $WinHand

$WinHand=GuiCreate("Muestra de uso de timers")
GuiSetState(@SW_SHOW)

$WinTimer=_Timer_SetTimer($WinHand, 5, "Win_Callback")
$Timer1=_Timer_SetTimer($WinHand, 5000, "Timer1_Callback")
$Timer2=_Timer_SetTimer($WinHand, 7000, "Timer2_Callback")

Func Timer1_Callback($hWnd, $Msg, $iIDTimer, $dwTime)
Msgbox(0, "", "Timer 1")
EndFunc

Func Timer2_Callback($hWnd, $Msg, $iIDTimer, $dwTime)
Msgbox(0, "", "Timer 2")
EndFunc

Func Win_Callback($hWnd, $Msg, $iIDTimer, $dwTime)
Local $_Msg
$_Msg=GuiGetMsg()
Select
Case $_Msg=$GUI_EVENT_Close
_Timer_KillTimer($WinHand, $Timer1)
_Timer_KillTimer($WinHand, $Timer2)
_Timer_KillTimer($WinHand, $WinTimer)
Exit
Case Else
Return
EndSelect
EndFunc

While 1
Sleep(60000)
Wend
Lo he hecho deprisa y corriendo, pero para que se vea el ejemplo creo que sirve.

Además, si os fijáis; para ver cosas raras que pasan con estas apis (aunque esto no debería ser tan raro) por lo menos yo le veo cierta lógica. Por ejemplo, en el bucle que mantiene el programa en ejecución, he puesto un sleep de un minuto, para que se vea que los timers pasan totalmente del bloqueo del programa. Supongo, que la explicación de por qué se comportan así las apis timer, debe ser, que funcionan llamando funciones callback, sin comprobar siquiera si estas han retornado o no, basándose solo en la frecuencia de ejecución que le indicamos al crear el timer.
De esa manera, da lo mismo que el script haya lanzado un msgbox() o esté ejecutando un bucle, los callbacks se supone que siempre están disponibles...

He puesto que el timer que muestra "mensaje 1" se lance cada 5 segundos, y el que muestra "mensaje 2" cada 7, para que veáis que sin aceptar "mensaje 1", se muestra "mensaje 2" y sin aceptar este, vuelve a mostrarse "mensaje 1", y así siempre (que era lo que yo decía), pero jugad con la frecuencia de ejecución, y veréis que aún con 0 msg es exactamente igual, solo que tendréis que reiniciar el pc cuando os aburráis de ver "MsgBox()" :).

Y, si queréis ver lo más raro que podáis imaginaros, probocad un error en el código (de sintaxis) de forma que al ejecutar el script de un error y esperad...
Es curioso ver como habiendo cascado el script, los timers siguen ejecutándose como si nada (dando error cada vez que se lanza el timer, por supuesto). Pero lo lógico sería digo yo, que si el programa ha dado un error el timer no se llegara almenos ni a crear. Y de hacerlo, al llamar Windows al callback del timer, si el programa ha fallado en la ejecución, La api que llama al callback debería dar un error o algo y no volver a ejecutarse (porque el callback se supone que no lo va a encontrar).
Vamos, que aunque medio entiendo esas cosas raras que hace, no dejan de ser cuanto menos ... curiosas :P.

Salu2!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Multihilo en autoit

Mensaje por Ximorro »

@Chefito, ¿cómo que "Por supuesto, en ambos casos seguía ejecutándose el código de las funciones aunque movieses la ventana."?

¡A mí se me para!
Mirad mi ejemplo, con AdlibRegister para poder registrar una función para cada GUI (versión 3.3.6, la anterior sólo podía tener una función Adbib activa con AdlibEnable).
No es que se pare el GUI que estás moviendo ¡¡es que se paran los dos!!

Código: Seleccionar todo

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>

Global $GUI1 = GUICreate("PRIMER GUI", 400, 160, 400, 200)
GUICtrlCreateLabel("CONTADOR 1:", 60, 33, 280, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
Global $lblContador1 = GUICtrlCreateLabel("1", 51, 57, 298, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
GUICtrlCreateLabel("", 50, 20, 300, 70, $SS_ETCHEDFRAME)
Global $btnSalir1 = GUICtrlCreateButton("&Salir", 150, 110, 100, 30)

Global $GUI2 = GUICreate("SEGUNDO GUI", 400, 160, 400, 450)
GUICtrlCreateLabel("CONTADOR 2:", 60, 33, 280, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
Global $lblContador2 = GUICtrlCreateLabel("1", 51, 57, 298, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
GUICtrlCreateLabel("", 50, 20, 300, 70, $SS_ETCHEDFRAME)
Global $btnSalir2 = GUICtrlCreateButton("&Salir", 150, 110, 100, 30)

GUISetState(@SW_SHOW, $GUI1)
GUISetState(@SW_SHOW, $GUI2)

Global $contador1 = 1, $contador2 = 1
AdlibRegister("_ActuContador1", 100)
AdlibRegister("_ActuContador2", 350)

While 1
	Switch GUIGetMsg()
		Case $btnSalir1, $btnSalir2, $GUI_EVENT_CLOSE
			ExitLoop
	EndSwitch
WEnd
AdlibUnRegister("_ActuContador1")
AdlibUnRegister("_ActuContador2")

Func _ActuContador1()
	$contador1 += 1
	GUICtrlSetData($lblContador1, $contador1)
EndFunc

Func _ActuContador2()
	$contador2 += 1
	GUICtrlSetData($lblContador2, $contador2)
EndFunc
@Jonny, claro que los timers interrumpen el Sleep, igual que las funciones Adlib. La otra manera de interrumpir la ejecución lineal de un script es con las funciones de evento en el modo OnEvent. ¿Por qué te sorprendes? Se trata de eso, con los timers se crea un proceso independiente en modo espera que es despertado pasado el tiempo especificado, momento en que ejecuta la función. Por eso se pueden simular threads con timers, claro, porque se ejecutan en threads diferentes...

Trabajar con errores no lleva a ninguna parte porque simplemente te encuentras con resultados inesperados. Al ser AutoIt un lenguaje interpretado la función se ejecuta y punto, si el resultado es mostrar un mensaje de error pues eso hará, pero como lo comprueba en tiempo de compilación, y en realidad la función existe, pues la ejecuta, aunque luego dé el error.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Multihilo en autoit

Mensaje por Ximorro »

Bueno Jonny, al final he tenido que hacerlo yo :smt027
Con Timers no se bloquea moviendo la ventana. No sé cómo habrán programado las funciones Adlib, porque seguro que programan algún timer para ello, pero bueno. Chefito decía que a él no se le bloqueaba, ¿será cosa del sistema? yo estoy en un viejo XP...

Os pongo abajo el código con timers. También se puede hacer con una sóla función (la he dejado comentada), aunque la compartan los timers tampoco se bloquean mutuamente (si usáis esa función hay que comentar las otras dos y poner en los dos timers ese mismo nombre de función)
También se pueden asignar los dos timers al mismo GUI, y tampoco quedan bloqueados. En este caso como cada timer actúa sólo sobre un GUI he preferido asignarlo cada uno al suyo.

Código: Seleccionar todo

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <Timers.au3>

Global $GUI1 = GUICreate("PRIMER GUI", 400, 160, 400, 200)
GUICtrlCreateLabel("CONTADOR 1:", 60, 33, 280, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
Global $lblContador1 = GUICtrlCreateLabel("1", 51, 57, 298, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
GUICtrlCreateLabel("", 50, 20, 300, 70, $SS_ETCHEDFRAME)
Global $btnSalir1 = GUICtrlCreateButton("&Salir", 150, 110, 100, 30)

Global $GUI2 = GUICreate("SEGUNDO GUI", 400, 160, 400, 450)
GUICtrlCreateLabel("CONTADOR 2:", 60, 33, 280, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
Global $lblContador2 = GUICtrlCreateLabel("1", 51, 57, 298, 20, $SS_CENTER)
GUICtrlSetFont(-1, 13, 800, 0, "Tahoma")
GUICtrlCreateLabel("", 50, 20, 300, 70, $SS_ETCHEDFRAME)
Global $btnSalir2 = GUICtrlCreateButton("&Salir", 150, 110, 100, 30)

GUISetState(@SW_SHOW, $GUI1)
GUISetState(@SW_SHOW, $GUI2)

Global $contador1 = 1, $contador2 = 1
Global $Timer1 = _Timer_SetTimer($GUI1, 100, "_ActuContador1")
Global $Timer2 = _Timer_SetTimer($GUI2, 350, "_ActuContador2")

While 1
	Switch GUIGetMsg()
		Case $btnSalir1, $btnSalir2, $GUI_EVENT_CLOSE
			ExitLoop
	EndSwitch
WEnd
_Timer_KillTimer($GUI1, $Timer1)
_Timer_KillTimer($GUI2, $Timer2)

Func _ActuContador1($hWnd, $Msg, $iIDTimer, $dwTime)
	#forceref $hWnd, $Msg, $iIDTimer, $dwTime
	$contador1 += 1
	GUICtrlSetData($lblContador1, $contador1)
EndFunc

Func _ActuContador2($hWnd, $Msg, $iIDTimer, $dwTime)
	#forceref $hWnd, $Msg, $iIDTimer, $dwTime
	$contador2 += 1
	GUICtrlSetData($lblContador2, $contador2)
EndFunc

;~ Func _ActuContador1($hWnd, $Msg, $iIDTimer, $dwTime)
;~ 	#forceref $hWnd, $Msg, $iIDTimer, $dwTime
;~ 	If $iIDTimer = $Timer1 Then
;~ 		$contador1 += 1
;~ 		GUICtrlSetData($lblContador1, $contador1)
;~ 	Else
;~ 		$contador2 += 1
;~ 		GUICtrlSetData($lblContador2, $contador2)
;~ 	EndIf
;~ EndFunc
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Multihilo en autoit

Mensaje por Chefito »

Ximorro escribió:@Chefito, ¿cómo que "Por supuesto, en ambos casos seguía ejecutándose el código de las funciones aunque movieses la ventana."?

¡A mí se me para!
Error garrafal por parte mía!!!! Me equivoqué :smt021 :smt010 . Es verdad, se paraba. Como no lo he probado la memoria me ha hecho una mala pasada :smt009 . Después de leerte me acardé que sí se paraba, pero como iba más suabe en llamadas muy rápidas dudé en utilizarlo a pesar de este fallo. Al final lo deseché, ya que no me gusta eso de que se pueda parar el script, y menos en lo que quiero hacer :smt002 .

Siento el error. Ximorro gracias por la corrección (como siempre) :smt023 .

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Responder