Is DWScript thread-safe?
Asked Answered
I

2

9

I would like to know if DWScript is capable of using threads inside of scripts, as some engines do not synchronize access to it's internal data structures.

Iciness answered 2/6, 2012 at 9:44 Comment(4)
-1 this question is trivially answered by reading the documentation, the front page of the DWScript project website, web search etc. Make some effort before asking the question.Jayejaylene
If the answer is that easy to find, then must certainly have skipped over it several times, or I wouldn't have posted the question.Iciness
@david: if everybody would just rtfm, there would be no stackoverflow :)Rigby
Your question was difficult to guess. "Using threads inside of scripts" was not obvious. Did you mean about compilation, runtime context, or within ONE script (with no S). The more explicit, the better. For instance, you may have spoken about "What is the DWS equivalence for TThread?". And as stated in my answer, you'll have the exact answer: nothing - DWS scripts are monothread execution stacks.Simonson
P
5

Arnaud gave the key points:

  • each compiler instance can only be invoked from one thread at a time. You can have multiple compiler instances invoked in multiple threads at the same time, and a particular compiler instance can be used from multiple threads, provided only one thread uses it a time.
  • each compiled program can have multiple executions, each execution can be running in its own thread. Also a particular execution can be used by several threads, provided only one thread uses it at a time.
  • each executions has its own space for its variables, and its own stack, object instances are on the heap and can technically be shared across executions, there is no locking mechanism for that, but you could make your own.
  • the script engine does not perform any synchronization or locking when using classes or functions exposed to it (be it via TdwsUnit, RTTI, etc.), so when running script executions in threads, make sure you only exposed thread-safe stuff (be particularly careful about that for RTTI, since lot of the RTL & VCL is not thread-safe to begin with)

Running multiple executions of a script is similar to having multiple threads in Delphi, though each new execution has not only its own stack (like Delphi threads) but also its own variable space (in Delphi it would be a bit like if you had "thread var" everywhere). And DWScript executions don't have to be in their own thread, they can be moved across threads, or polled and used in a lower number of threads (the only limitation being that each execution is used by only one thread at a time, as mentioned above).

So nothing prevents you from exposing a function that would spawn a thread (and corresponding execution) in a script function, but communication across the executions wouldn't be via shared variables (like you could be tempted to do in Delphi), but would have to go through your own exposed functions (or external variables), return values (using an "evaluate" approach, cf. the unit tests), "shared" object instances, or "global vars".

By "global vars", I mean the functions defined in dwsGlobalVarsFunctions.pas, which can be used for inter-execution data exchange. To activate them, just have a "uses dwsGlobalVarsFunctions" somewhere in your project.

They expose a set of Read/WriteGlobalVar functions, which allow storing and retrieving named variants across all script executions running within the same Delphi process, and those reads & writes are "atomic" from a threading point of view.

Piercy answered 4/6, 2012 at 6:3 Comment(3)
Nice having the DWS "god father" (or new dad) in SO! :)Simonson
When a TdwsProgramExecution object is being executed in a thread, can another thread call TdwsProgramExecution.EndProgram safely?Iciness
No, but you can call Stop for that (which also works if you executed by Execute(), rather than manually with BeginProgram/RunProgram). That will cause the script to abort at the earliest opportunity under its control, ie. if your script is running a Delphi function, it'll only stop after returning from that function. EndProgram does cleanups and is meant to be called from the executing thread.Piercy
S
4

It was not even necessary to open DWS documentation. :)

Just take a look at this StackOverflow answer by Eric:

For instance, [DWS] is now capable of multiple thread-safe executions of a single compiled script, while the old codebase is built around the limitation that a compiled script can be executed by only one thread at a time.

In short:

  • The DWS compiler is not thread-safe: you have to create the execution stack within one thread (you can't share a compiler instance, you need one thread per compiler instance);
  • The DWS execution is thread-safe, if you use one execution instance per thread: you can run the same compiled script in several threads;
  • Communication between threads are not available AFAIK, but you may use Delphi code if you need synchronization.

Of course, here is the official documentation page about thread safety in DWS.

You can now have as many program executions for a given IdwsProgram as you wish, each execution will use memory for its heap & stack only, the compiled expression tree is shared. Both new interfaces use reference-counted memory management.

Simonson answered 3/6, 2012 at 16:13 Comment(2)
Reading this through, I realized that I already know this, but unless I'm wrong, it doesn't quite answer my question... I don't want to be running the same script in multiple threads, I want to be running multiple threads inside of a single script...Iciness
AFAIK so far I understand the execution class implementation, it is not possible, by design. There is no TThread or such. The only possibility will be to run several scripts inside a thread for each (this is possible, of course), then try to make to IPC or mutex between the scripts, just as I wrote in my 3rd point: there is not between thread communication available from scratch. I'd rather recommend a stateless architecture, with some shared data structures made available by Delphi classes (e.g. exposed using RTTI into DWS).Simonson

© 2022 - 2024 — McMap. All rights reserved.