2010-06-04 15 views
8

Ich hatte neulich ein Gespräch mit meinem Freund. Ich habe gesagt, dass man in reinem Lua kein präemptives Multitasking-System aufbauen kann. Er behauptet, dass Sie das können, aus folgendem Grund:Multithreading in Lua

Sowohl C als auch Lua haben keine eingebaute Threading-Bibliotheken [Anmerkung des OP: Nun, Lua technisch, aber AFAIK ist es nicht für unsere Zwecke nützlich]. Windows, das größtenteils in C (++) geschrieben ist, hat präemptives Multitasking, das sie von Grund auf neu erstellten. Daher sollten Sie in der Lage sein, das Gleiche in Lua zu tun. Das große Problem, das ich damit sehe, ist, dass das präemptive Multitasking (meines Wissens nach) hauptsächlich darin besteht, dass es regelmäßige Interrupts erzeugt, mit denen der Manager die Kontrolle erhält und festlegt, an welchem ​​Code er als nächstes arbeiten soll. Ich glaube auch nicht, dass Lua irgendeine Einrichtung hat, die das kann.

Meine Frage ist: ist es möglich, eine Pure-Lua-Bibliothek zu schreiben, die Menschen vorbeugende Multitasking haben können?

+0

FYI Dies ist keine Antwort auf Ihre Frage (reine Lua-Implementierung von Multithreading), aber für jemanden, der nur Lue-Code mehrere OS-Threads ausführen und sie präventiv planen möchte, gibt es viele Optionen: http: // kotisivu. dnainternet.net/askok/bin/lanes/comparison.html – pts

Antwort

7

Ich kann nicht sehen, wie es geht, obwohl ohne eine formale Semantik von Lua (wie die Semantik von yield zum Beispiel), es ist wirklich schwer, mit einem eisernen Argument zu kommen, warum es nicht getan werden kann. (Ich habe, eine formale Semantik für Alter will aber offenbar Roberto und lhf haben Besseres zu tun.)

Wenn ich präemptive Multitasking für Lua wollte, würde ich nicht einmal versuchen, es zu tun in reines Lua. Stattdessen würde ich einen alten Trick ich zum ersten Mal vor 20 Jahren sah in Standard ML von New Jersey:

  • Interrupt einen Flag im lua_State setzt sagen "aktuelle Koroutine preempted wurde".

  • Ändern Sie die VM so, dass sie bei jeder Schleife und jedem Funktionsaufruf das Flag prüft und bei Bedarf nachgibt.

Dieser Patch wäre einfach zu schreiben und einfach zu pflegen. Es löst nicht das Problem der lang laufenden C-Funktion, das nicht vorweggenommen werden kann, aber wenn Sie dieses Problem lösen müssen, wandern Sie in viel härteres Gebiet, und Sie können genauso gut Ihr gesamtes Threading erledigen die C-Ebene, nicht die Lua-Ebene.

+0

Danke für die Info :) – RCIX

+0

"Ändern Sie die VM so, dass bei jeder Schleife und jedem Funktionsaufruf die Markierung überprüft und ggf. ausgegeben wird." Wir haben das damals gemacht, als wir mit den ersten Versionen von Smalltalk entwickelt haben, die auch nicht präemptiv waren. Was passierte, war, dass die Hölle losbrach. Plötzlich gab es Erträge in Zeiten, in denen sie nicht früher passierten. Dies führte zu vielen Mutexbereichen, die nicht ordnungsgemäß synchronisiert wurden, um in Kontextwechsel zu wechseln und veraltete Daten zu erzeugen. Vielleicht erbt LuaJ das präemptive Multithreading in Java? – OlliP

5

Nicht, dass ich weiß, nein. Es wäre fast schon absurd einfach, wenn man mit Hilfe von debug.sethook von Hooks, die auf Coroutinen gesetzt wurden, profitieren könnte, aber es funktioniert nicht. Sie können Ausbeute von C-Haken von C gesetzt (lua_sethook), aber ich konnte genau nicht herausfinden, und das ist nicht pure Lua sowieso.

Selbst wenn es möglich wäre, wäre es nicht richtig Threading. Alles würde immer noch innerhalb desselben Betriebssystem-Threads laufen. Ihr Hook würde eine Vielzahl von Faktoren berücksichtigen (wie Zeit, vielleicht Speicher usw.) und dann bestimmen, ob er nachgibt. Die Coroutine würde dann entscheiden, welche Kindercoroutine als nächstes ausgeführt werden soll. Sie müssen auch entscheiden, wann der Hook aufgerufen werden soll. Am häufigsten würde es bei jedem Lua-Unterricht sein, aber das bringt eine Leistungseinbuße mit sich. Und wenn die Coroutine eine C-Funktion aufruft, hat Lua keine Zuständigkeit. Wenn dieser C-Aufruf lange dauert, können Sie nichts dagegen tun.

Here ist ein verwandter Thread aus der Lua-L Mailingliste, den Sie vielleicht interessant finden.

+0

Supreme Commander verwendet solch ein "falsches" Threading-System, obwohl es eine benutzerdefinierte Optimierung von Lua hat, denke ich. Das war es, was die Frage inspirierte :) – RCIX

+0

Ehrlich gesagt, würde ich _love_ in der Lage sein, so etwas zu tun. Es würde ein paar Probleme machen, die ich viel einfacher zu handhaben anständig. – Twisol

5

Nein. Es ist nicht möglich, einen präemptiven Scheduler in reinem Lua zu schreiben.An einem gewissen Punkt benötigt ein präventiver Scheduler einen Mechanismus wie eine Interrupt-Service-Routine, um die Steuerung vom aktuellen Thread wegzunehmen und sie dem Scheduler zu übergeben, der sie dann einem anderen Thread geben kann. Reines Lua hat diesen Mechanismus nicht.

Sie erwähnen, dass Windows hauptsächlich in C/C++ geschrieben ist. Das Schlüsselwort ist meistens. Sie können einen preemptive Scheduler in reinem ANSI C/C++ nicht schreiben. Normalerweise wird ein Teil der Interrupt-Service-Routine in Assembler geschrieben. Oder der C/C++ - Compiler implementiert eine nicht standardmäßige Erweiterung, die es ermöglicht, Interrupt-Service-Routinen in C/C++ zu schreiben. Einige Compiler ermöglichen es Ihnen, Funktionen mit einem __interrupt-Modifizierer zu deklarieren, der bewirkt, dass der Compiler einen prolong/epilog generiert, der es ermöglicht, die Funktion als Interrupt-Service-Routine zu verwenden.

Auch Code, der die Interrupt-Service-Routine eingerichtet fiddles mit CPU-Registern mit Memory-Mapped IO, oder eine IO-Anweisungen. Keiner dieser Code ist portable ANSI C/C++. Und, hängt von der CPU-Architektur ab.