2012-06-02 18 views
8

Ich würde gerne wissen, ob DWScript Threads innerhalb von Skripten verwenden kann, da einige Engines den Zugriff auf ihre internen Datenstrukturen nicht synchronisieren.Ist DWScript Thread-sicher?

+0

-1 Diese Frage wird trivial beantwortet, indem Sie die Dokumentation, die Startseite der DWScript-Projektwebsite, die Websuche usw. lesen. Machen Sie sich etwas Mühe, bevor Sie die Frage stellen. –

+1

Wenn die Antwort so einfach zu finden ist, dann muss sie sicherlich mehrmals übersprungen worden sein, sonst hätte ich die Frage nicht gestellt. – FHannes

+4

@david: wenn jeder nur rtfm wäre, gäbe es keinen stackoverflow :) –

Antwort

4

Arnaud gab die wichtigsten Punkte:

  • jedes Compiler Beispiel von einem Thread zu einem Zeitpunkt nur in Anspruch genommen werden kann. Sie können mehrere Compiler-Instanzen gleichzeitig in mehreren Threads aufrufen, und eine bestimmte Compiler-Instanz kann aus mehreren Threads verwendet werden, vorausgesetzt, nur ein Thread verwendet sie jeweils einmal.
  • Jedes kompilierte Programm kann mehrere Ausführungen haben, jede Ausführung kann in einem eigenen Thread ausgeführt werden. Eine bestimmte Ausführung kann auch von mehreren Threads verwendet werden, vorausgesetzt, dass jeweils nur ein Thread sie verwendet.
  • Jede Ausführung hat seinen eigenen Platz für seine Variablen, und sein eigener Stapel, Objektinstanzen sind auf dem Heap und können technisch über Ausführungen verteilt werden, es gibt keinen Sperrmechanismus dafür, aber Sie könnten Ihren eigenen erstellen.
  • Die Skript-Engine führt keine Synchronisierung oder Sperrung durch, wenn Klassen oder Funktionen verwendet werden, die ihr ausgesetzt sind (sei es über TdwsUnit, RTTI usw.).), So dass, wenn Skriptausführungen in Threads ausgeführt wird, stellen Sie sicher, dass Sie nur für RTTI Thread-sichere Sachen (besonders vorsichtig sein, darüber ausgesetzt, da viel von der VCL RTL & nicht Thread-sicher ist mit)

zu beginnen Das Ausführen mehrerer Ausführungen eines Skripts ist ähnlich wie bei mehreren Threads in Delphi, obwohl jede neue Ausführung nicht nur einen eigenen Stapel (wie Delphi-Threads), sondern auch einen eigenen Variablenraum hat (in Delphi wäre es ein bisschen wie bei "thread") var "überall". Und DWScript-Ausführungen müssen nicht in einem eigenen Thread sein, sie können über Threads verschoben oder abgefragt und in einer geringeren Anzahl von Threads verwendet werden (die einzige Einschränkung ist, dass jede Ausführung nur von einem Thread gleichzeitig verwendet wird, wie z oben erwähnt).

Nichts hindert Sie daran, eine Funktion offen zu legen, die einen Thread (und die entsprechende Ausführung) in einer Skriptfunktion erzeugt, aber die Kommunikation über die Ausführungen würde nicht über gemeinsame Variablen erfolgen (wie Sie in Delphi versucht werden könnten) , würde aber Ihre eigenen exponierten Funktionen (oder externen Variablen), Rückgabewerte (mit einem "evaluate" -Ansatz, siehe Unit-Tests), "shared" Objektinstanzen oder "global vars" durchlaufen müssen.

Mit "global vars" meine ich die in dwsGlobalVarsFunctions.pas definierten Funktionen, die für den Inter-Execution-Datenaustausch verwendet werden können. Um sie zu aktivieren, verwenden Sie einfach "uses dwsGlobalVarsFunctions" irgendwo in Ihrem Projekt.

Sie stellen eine Reihe von Read/WriteGlobalVar-Funktionen zur Verfügung, die das Speichern und Abrufen benannter Varianten über alle Skriptausführungen innerhalb desselben Delphi-Prozesses ermöglichen, und die Lesevorgänge & sind vom Standpunkt des Threads aus "atomar".

+1

Schön, dass der DWS "Gottvater" (oder neuer Vater) in SO! :) –

+0

Wenn ein TdwsProgramExecution-Objekt in einem Thread ausgeführt wird, kann ein anderer Thread TdwsProgramExecution.EndProgram sicher aufrufen? – FHannes

+0

Nein, aber Sie können Stop dafür aufrufen (was auch funktioniert, wenn Sie mit Execute() und nicht manuell mit BeginProgram/RunProgram ausgeführt wurden). Dadurch wird das Skript zum frühestmöglichen Zeitpunkt unter seiner Kontrolle abgebrochen, d. Wenn Ihr Skript eine Delphi-Funktion ausführt, wird es erst nach der Rückkehr von dieser Funktion gestoppt. EndProgram führt Bereinigungen durch und soll vom ausführenden Thread aufgerufen werden. –

3

Es war nicht einmal notwendig, die DWS-Dokumentation zu öffnen. :)

Werfen Sie einen Blick at this StackOverflow answer by Eric:

Zum Beispiel [DWS] ist nun in der Lage mehrere Thread-sichere Ausführungen eines einzigen kompilierten Skript, während die alte Codebasis um die Begrenzung gebaut dass ein kompiliertes Skript nur von jeweils einem Thread ausgeführt werden kann.

Kurz:

  • Der DWS-Compiler ist nicht Thread-sicher: Sie können den Ausführungsstapel in einem Thread erstellen haben (man kann nicht einen Compiler Instanz teilen, benötigen Sie einen Thread pro Compiler-Instanz);
  • Die DWS-Ausführung ist Thread-sicher, wenn Sie eine Ausführungsinstanz pro Thread verwenden: Sie können dasselbe kompilierte Skript in mehreren Threads ausführen;
  • Kommunikation zwischen Threads ist nicht verfügbar AFAIK, aber Sie können Delphi-Code verwenden, wenn Sie Synchronisierung benötigen.

Natürlich ist hier the official documentation page about thread safety in DWS.

Sie können jetzt so viele Programmausführungen für eine gegebene IdwsProgram wie Sie es wünschen, jede Ausführung nur Speicher für seinen Haufen & Stack verwenden, die kompilierte Ausdrucksbaum geteilt wird. Beide neuen Schnittstellen verwenden eine reference-gezählte Speicherverwaltung.

+1

Als ich dies durchgelesen habe, habe ich gemerkt, dass ich das bereits weiß, aber wenn ich nicht falsch liege, beantwortet es meine Frage nicht ganz ... Ich möchte nicht dasselbe Skript in mehreren Threads ausführen, das möchte ich sein mehrere Threads in einem einzigen Skript laufen lassen ... – FHannes

+1

AFAIK soweit ich die Implementierung der Ausführungsklasse verstehe, ist es nicht möglich, durch Design. Es gibt kein TThread oder so. Die einzige Möglichkeit wird sein, mehrere Skripte innerhalb eines Threads für jeden auszuführen (das ist natürlich möglich), dann versuche, IPC oder Mutex zwischen den Skripten zu machen, genau wie ich in meinem 3. Punkt geschrieben habe: Es gibt keine Thread-Kommunikation von Grund auf neu verfügbar. Ich würde eher eine zustandslose Architektur mit einigen gemeinsamen Datenstrukturen empfehlen, die von Delphi-Klassen zur Verfügung gestellt werden (z. B. durch Verwendung von RTTI in DWS). –