Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

23.08.2009, 17:08

Multithreading mit Lua

Hi,

in meinem aktuellen Projekt ist es notwendig, dass ich aus mehreren Threads gleichzeitig auf Funktionen eines Lua Skripts zugreifen kann.

Das oben beschriebene einfach zu implementieren (also pccall auf die selbe Lua VM aus unterschiedlichen Threads) führt unweigerlich zu Abstürzend, welche in Lua internen Funktionen entstehen.

Die Serialisierung mittel Mutex auf den Zugriff verhindert zwar die Abstürze, jedoch wird die Ausführung der Skripte stark verlangsam, da jetzt eine Warteschlange entsteht, die nacheinander abgearbeitet wird.

Mein Gedanke war zuerst einfach die VM komplett neu anzulegen und alle Inhalte aus der alten VM zu kopieren. Hier habe ich aber das Problem, das ich nicht alle Objekte und Variablen der VM verstehen (wenn das einer geschafft hat, wäre ich für Hinweise dankbar).

Auf lua-users.org hatte jemand ein ähnliches vorhaben. Ihm wurde gerate einfach ein neuen LuaThread zu erstellen. Dieser würde die gleiche VM benutzen, jedoch einen eigenen Stack haben.

schien gut für mich zu sein, weswegen ich das gleich implementiert hatte.

Jetzt bekomme ich den Fehler "Zugriffsverletzung beim Lesen an Position 0x0000000c" an der Stelle "if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */" in der Datei "lgc.c"


Sollte jemand von euch schonmal multithreading mit Lua hin bekommen haben, währe ich für einen hinweis, wie das zu lösen ist, sehr dankbar.

Ich werde es zwischenzeitlich weiter versuchen und bin schon sehr auf die Lösung gespannt.

Grüße Chriss

2

26.08.2009, 15:36

Also für diejenigen, die es interessiert.

Das erzeugen eines Threads mit der Funktion lua_newthread ist etwas, das man nicht mit mehreren Threads machen sollte, da es zum Ansturz führt.

Das manuelle kopieren von lua_State bringt auch nicht so viel.
Grund ist, das in den Internas von Lua die Struktur global_State verwendet wird. lua_State ist eigentlich nur der Stack, der auf global_State verweist.

Probleme entstehen also durch das Verändern des global_State in mehreren Threads.

Da es mir zu mühselig ist, alle lua funktionen durch zu gehen und nachzusehen, wie dieser global_Stack erzeugt und verwendet wird, bin ich einen anderen Weg gegangen.



Ich lade jetzt die Skriptdatei in ein char Array und lasse mir daraus bei Bedarf ein neu VM (lua_State) erzeugen,welche ich dann verwende. Bei vorkompilierten Skripten liefert das eigentlich ein gutes Ergebnis und bei normalen Skripten läuft es für die Entwicklung schnell genug.

Die VM erzeuge ich dann so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
lua_State *L;
char *buffer;
int bufferLength;

// Skript laden und Buffer füllen

// . . .


// VM anlegen

lua_open(L);

// Skript in die VM laden

luaL_loadbuffer(*L,buffer,bufferLength,"Skriptname");

// Skript ausfüren und Funktionen verfügbar machen

lua_pcall(*L, 0, LUA_MULTRET, 0);


Nicht schön, aber funktioniert in einer akzeptablen Geschwindigkeit.

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

3

26.08.2009, 15:55

Ist diese Lösung wirklich schneller (zumindestens in deinem Szenario, allgemein ist das sicherlich von Fall zu Fall verschieden) als, wie im ersten Post von dir beschrieben, mit Mutexen zu arbeiten und eben aufzupassen, dass immer nur vom "richtigen" Thread aus gearbeitet wird?

4

26.08.2009, 18:38

In meinem Fall ist es schneller (meistens).
Bei kurzen Skripten könnte es sogar schneller sein zu serialisieren (anstelle meiner Lösung).

Bei mir kommt es stark auf die Reaktionszeit an und später werden Skripte noch sleep verwenden können.

Aber eine wirklich gute Lösung ist das nicht.
In Zukunft werde ich mich wohl mehr mit Lua beschäftigen müssen um eine VM wirklich klonen zu können.

Werbeanzeige