2010-06-04 13 views
8

Estaba teniendo una conversación con mi amigo el otro día. Estaba diciendo que, en pura Lua, no podrías construir un sistema de multitareas preventivo. Afirma que puede, por el siguiente motivo:Multithreading en Lua

Tanto C como Lua no tienen bibliotecas de subprocesos incorporadas [Nota de OP: bueno, técnicamente Lua lo hace, pero AFAIK no es útil para nuestros propósitos]. Windows, que está escrito en su mayoría en C (++), tiene multitarea preferente, que construyeron desde cero. Por lo tanto, deberías poder hacer lo mismo en Lua. El gran problema que veo con eso es que la forma principal en que funciona la multitarea preventiva (que yo sepa) es que genera interrupciones regulares que el administrador usa para obtener el control y determinar en qué código debería estar trabajando a continuación. Tampoco creo que Lua tenga ninguna facilidad que pueda hacer eso.

Mi pregunta es: ¿es posible escribir una biblioteca pura de Lua que permita a las personas realizar múltiples tareas preventivas?

+0

FYI Esta no es una respuesta a su pregunta (implementación Lua pura de subprocesamiento múltiple), pero para alguien que solo quiere ejecutar el código Lue en múltiples subprocesos OS y programarlos de manera preventiva, hay muchas opciones: http: // kotisivu. dnainternet.net/askok/bin/lanes/comparison.html – pts

Respuesta

7

No puedo ver cómo hacerlo, aunque sin una semántica formal de Lua (como la semántica de yield por ejemplo), es realmente difícil encontrar un argumento claro por qué no se puede hacer. (He estado esperando una semántica formal para las edades, pero es evidente que Roberto y LHF tengo cosas mejores que hacer.)

Si quería multitarea preventiva para Lua, que ni siquiera tratar de hacerlo en Lua puro. En su lugar me gustaría usar un viejo truco vi por primera vez hace 20 años en el ml estándar de Nueva Jersey:

  • interrupción establece un indicador en el lua_State diciendo "co-rutina actual ha sido apropiado".

  • Modifique la máquina virtual para que en cada ciclo y cada llamada a función, compruebe el indicador y ceda si es necesario.

Este parche sería fácil de escribir y fácil de mantener. No resuelve el problema de la función C de larga ejecución que no se puede descartar, pero si tiene que resolver ese problema, se está adentrando en un territorio mucho más difícil, y también puede hacer todos los subprocesos en el nivel C, no el nivel Lua.

+0

Gracias por la información :) – RCIX

+0

"Altere la VM para que en cada bucle y en cada llamada a la función, compruebe el indicador y ceda si es necesario". Hicimos esto en aquel entonces cuando desarrollamos las primeras versiones de Smalltalk que tampoco eran preventivas. Lo que sucedió fue que el infierno se desató. De repente, los rendimientos estaban sucediendo en momentos en que no ocurrían antes. Esto dio como resultado muchas áreas mutex que no se sincronizaron apropiadamente para ejecutar interruptores de contexto y crear datos obsoletos. ¿Quizás LuaJ hereda el multihilo preventivo en Java? – OlliP

5

No es que yo sepa, no. Sería casi absurdamente simple si pudieras ceder desde ganchos establecidos en coroutines con debug.sethook, pero no funciona. Usted puede rendimiento de C ganchos establecidos desde C (lua_sethook), pero no pude averiguar exactamente para hacer eso, y no es puro Lua de todos modos.

Incluso si fuera posible, no sería cierto enhebrar. Todo seguiría ejecutándose dentro del mismo hilo del sistema operativo, por ejemplo. Su anzuelo tomaría en cuenta una variedad de factores (como el tiempo, quizás la memoria, etc.) y luego determinaría si ceder o no. La corutina cedida decidirá qué coroneta infantil ejecutará a continuación. También necesitaría decidir cuándo se debe llamar al gancho. Lo más frecuente sería en cada instrucción Lua, pero eso conlleva una penalización de rendimiento. Y si la coroutine llama a una función C, Lua no tiene jurisdicción. Si esa llamada de C tarda mucho tiempo, no hay nada que puedas hacer al respecto.

Here es un hilo relacionado de la lista de correo de Lua-L que puede parecer interesante.

+0

Supreme Commander utiliza un sistema de subprocesamiento "falso", aunque tiene un ajuste personalizado de lua, creo. Eso fue lo que inspiró la pregunta :) – RCIX

+0

Francamente, me gustaría poder hacer este tipo de cosas. Haría algunos problemas con los que me encuentro mucho más fácil de manejar decentemente. – Twisol

5

No. No es posible escribir un programador preventivo en Lua puro.En algún punto, un planificador preventivo necesita algún mecanismo, como una rutina de servicio de interrupción, para quitar el control del hilo actual y entregárselo al programador, que luego puede pasarlo a otro hilo. Pure Lua no tiene este mecanismo.

Menciona que Windows está escrito principalmente en C/C++. La palabra clave es en su mayoría. No puede escribir un planificador preventivo en puro ANSI C/C++. Por lo general, parte de la rutina del servicio de interrupción está escrita en lenguaje ensamblador. O bien, el compilador C/C++ implementa una extensión no estándar que permite escribir rutinas de servicio de interrupción en C/C++. Algunos compiladores le permiten declarar funciones con un modificador de interrupción __ que hace que el compilador genere un prolong/epilog que permite que la función se use como una rutina de servicio de interrupción.

Además, el código que configura la rutina de servicio de interrupción juguetea con los registros de la CPU con la IO asignada de memoria o con las instrucciones IO. Ninguno de este código es portátil ANSI C/C++. Y, depende de la arquitectura de la CPU.