Ejecutar procesos en paralelo con lanes (Multithread en AMS)

Ejemplos y plantillas para Autoplay Media Studio.
Hola, mi aporte de hoy buscará enseñarles como ejecutar varios procesos en paralelo sin que la aplicación se quede congelada (esto puede servir por ejemplo para descargar un archivo en segundo plano, hacer un backup o lo que se les ocurra).

En otros lenguajes de programación esto seria relativamente más fácil de hacer pero como saben Lua no es multithread (en realidad la belleza de Lua radica en la simplicidad y por esto no puede hacer demasiadas cosas por si solo pero...) para eso tenemos los módulos o librerías, hoy vengo a mostrarles mi implementación de el modulo lanes que nos ayudará a crear procesos en paralelo en nuestra aplicación. Si bien lo único que tenemos que hacer es importar el módulo la verdad es que cabe explicarlo, al menos para mi fue difícil lograrlo la primera vez, la documentación se me hizo un poco confusa.

Explicaré como implementar de una manera útil el modulo y sobretodo fácilmente para evitar confusiones solo haré lo básico si alguien quiere más información puede leer la documentación oficial de el módulo.

Lo primero es resaltar que con los lanes no podemos por ejemplo cambiar una variable global porque los datos estan separados por defecto, pero podemos lograr compartir datos entre los threads mediante objetos linda y así cambiar dicha variable.

La función lanes.gen() es un generador que nos devuelve una función que se ejecutará en un proceso diferente del sistema, un poco de código lo explicará mejor:
require "lanes"
-- Generamos nuestra funcion:
Saludo = lanes.gen( function(name) 
  return "Hola " .. name -- Retornamos el saludo
end)

a = Saludo("Valentina") -- Llamamos
b = Saludo("Anthony")  -- Volvemos a llamar

print (a[1], b[1]) -- Devolverá > Hola Valentina      Hola Anthony
Con esto conseguimos que los resultados de a = Saludo() y b = Saludo() sean calculados en procesos separados.

Ahora un ejemplo un poco más útil, utilizaremos un objeto linda para enviar y recibir valores, dentro del lane habrá un bucle for que contara de 1 hasta 28 millones.

Luego un bucle while que se encargará de recibir e imprimir los datos que nos esta enviando el bucle for desde el otro proceso:
require "lanes"
linda = lanes.linda() -- Creamos el objeto linda

-- Los lanes permiten definir librerias que estarán disponibles para la función, con los dos primeros argumentos le estamos diciendo que nos deje utilizar todas las funciones que tenemos disponibles en nuestro entorno..

Bucle = lanes.gen("*", {globals=_G}, function(name)  
  for i=1, 28000000 do -- Iniciamos el bucle for
    -- El argumento name sera la "key" que nos permitirá pasar valores entre threads (Muy util tener varias keys para varios procesos, no recomiendo tener varios objetos linda y tampoco sé si está permitido)
    key = name 
    value = i
    linda:set(key, value)  -- Seteamos el valor
  end

end)

Bucle("Dario") -- Ejecutamos nuestra funcion lanes y le damos como argumento "Dario" (Esta será la key)

-- Como nuestra funcion esta en otro proceso del sistema no esperará hasta que termine, pasará automaticamente aqui y ejecutará este bucle:
while true do
  print(linda:get("Dario")) -- Imprimimos lo que haya en nuestra key "Dario"
end

Esto es lo más básico que se requiere saber para ejecutar funciones en diferentes procesos del sistema, dejo un apz para que vean el funcionamiento básico y puedan empezar a utilizarlo en sus proyectos, en el ejemplo hay tres botones que se usaran para ejecutar cada uno de los procesos que nunca congelarán la aplicación :)

Imagen

Descargar ejemplo:

HIDE: ON
Hidebb Message Hidden Description


Entre otras cosas el modulo lanes tambien nos permite ejecutar timers, cancelar nuestros lanes, verificar errores. Ninguno de estos conceptos está explicado aquí pero pueden leer la documentación para orientarse un poco más.

Documentación:

Código: Seleccionar todo

http://cmr.github.io/lanes/
Saludos desde Colombia
Yo ya he jugado a esto antes, y hay que decirlo, esto está bien para usar con LUA, pero no es Autoplay.

El problema de autoplay es sencillamente que sus funciones en el runtime corren en el mismo thread, asi que para utilizar funcionalidades de autoplay, por ejemplo http.download, con lanes o con lo que sea la ejecucion corta inyección. Tan simple. La solucion evidente es no usar api de autoplay en los threads pero entonces donde esta la gracia...

Mi obejeto de MultiThread era buena idea en cuanto a que crea threads reales y LuaStates nuevos en cada thread, heredados del principal pero al ser el runtime de ams como esta no se puede... Pero es mucho mas sencillo de usar que lanes, eso, si...

thanks

Una de las grandes frustraciones del ams, por lo general es con le tema http... para lo demas, hay soluciones básicas que minimiza el bloqueo de la app... por ejemplo con wget.exe, realizo todas las taras http que necesite, enviando los parámetros necesarios, creando algunos .vbs y demás para una ejecución mas limpia sin la ventana msdos... para procesos locales la verdad no he llegado hasta allá pero es bueno probar y tener sus propias conclusiones

xk Autoplay es limitado es thread gracias

:pc: :pc: :pc:
manda pra mim
Veamos :lol: :lol: :lol: :lol: :lol:
Gracias
se ve muy bueno espero que enlace todavia sirva
Gracias, espero este disponible
thanks
gracias
good thanks
thanksssssssss
gracias
Gracias :pc:
gracias
thankssssssssssssssssssss