QtScript and threads

1.6k views Asked by At

I want to run several concurrent jobs from QtScript script:

function job1() { ... }
function job2() { ... }

runConcurrentJobs(job1, job2)

The jobs a essentially sequences of remote procedure calls (ZeroC Ice), which need to synchronize at several points.

The Qt 4.8.0 documentation says nothing about QScriptEngine thread-safety. My questions:

  1. Is it safe to use single QScriptEngine to exectute QtScript functions from multiple thread concurrently?

  2. What approach would you recommend to accomplish the task?

Notes:

  1. Scripts are edited not by programmers but also by electric engineers and I want to keep the script as simple and clean as possible.
2

There are 2 answers

2
Ben On
  1. In general, if documentation says nothing about threading, it is not thread safe.

  2. I would rewrite to use asynchronous requests. Just kick them both off, then wait for them both.

0
Tfry On

QScriptEngine is documented as "reentrant", meaning, essentially, you can use it multi-threaded, but only one QScriptEngine per thread.

Now, if functions job1() and job2() can be run concurrently at all, in principle, it should be possible to separate them into two distinct QScriptEngines (easy, if neither the functions use local variables, only, more difficult, if globals are involved).

  1. Implement runConcurrentJobs() as a Q_INVOKABLE function (or slot) in C++.
  2. In there, do something like

       void runConcurrently (const QString &functionname1, QString &functionname2) {
           MyScriptThread thread1 (functionname1);
           MyScriptThread thread2 (functionname2);
           thread1.start();
           thread2.start();
           thread1.wait ();
           thread2.wait ();
           // optionally fetch return values from the threads and return them
       }
    
  3. Where MyScriptThread is derived from QThread and implements QThread::run() roughly like this:

       void MyScriptThread::run () {
             QScriptEngine engine;
             engine.evaluate (common_script_code);
             result = engine.evaluate (the_threads_function);
             // the_threads_function passed as a QScriptProgram or QString
       }