2

I need to run multiple (up to 50 or more) Qt Script Functions concurrently. Running two or three Threads with Script Functions works just fine, but as soon as I run around 50 Threads, I get an Error and my Program crashes.

ASSERTION FAILED: globalData().dynamicGlobalObject (..\3rdparty\javascriptcore\JavaScriptCore\runtime/JSGlobalObject.h:411 QTJSC::JSGlobalObject* QTJSC::ExecState::dynamicGlobalObject())

My main.cpp looks like this:

#include <QCoreApplication>
#include <QScriptEngine>
#include <threadworker.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QScriptEngine engine;
    QScriptValue val = engine.evaluate("(function() {var r = Math.random(); while(1>0) print(r);})");
    ThreadWorker *worker[50];
    for(int i=0;i<50;i++) {
        worker[i] = new ThreadWorker(val);
        QObject::connect(worker[i], SIGNAL(needsStarting()), worker[i], SLOT(startScript()));
        emit worker[i]->needsStarting();
    }
    return a.exec();
}

This is my threadworker.h:

#ifndef THREADWORKER_H
#define THREADWORKER_H

#include <QObject>
#include <QScriptValue>
#include <QThread>

class ThreadWorker : public QObject
{
    Q_OBJECT
public:
    explicit ThreadWorker(QObject *parent = 0);

    explicit ThreadWorker(QScriptValue function);

signals:
    needsStarting();
public slots:
    void startScript();
private:
    QScriptValue value;
    QThread thread;
};

#endif // THREADWORKER_H

This is my threadworker.cpp:

#include "threadworker.h"
#include <QDebug>

ThreadWorker::ThreadWorker(QObject *parent) : QObject(parent)
{
}

ThreadWorker::ThreadWorker(QScriptValue function)
{
    value = function;
    this->moveToThread(&thread);
    thread.start();
}

void ThreadWorker::startScript()
{
    value.call();
}

I expected, that independently of the amount, the Qt Script Threads would run just fine and I can't understand what is causing this contrary behaviour.

2
  • did you try to create threads in main() and moving those object into those threads in main() too? Commented Apr 24, 2017 at 10:46
  • @ni1ight just tried it. Doesn't change anything. Still the same problems. Commented Apr 24, 2017 at 11:13

1 Answer 1

1

Putting the QScriptEngine on worker class and let moveToThread move it to the the worker thread, seems to solve:

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);

public slots:
    void startScript(const QString &function);

private:
    QScriptEngine engine;
    QScriptValue value;
};

However, it will be a challenge create so many threads and release them properly on application exit. I suggest you to use pooled threads, for example, QtConcurrent. QtConcurrent allows you (for example but not limited to) multithread with just functions, not necessarly classes, and with QFutureSyncronyzer you can in one call wait for all the threads you want to finish. See QtConcurrent:

#include <QtScript>
#include <QtConcurrent>

#define THREADS 50

void worker_function(const QString &function)
{
    QScriptEngine engine;
    QScriptValue value;

    value = engine.evaluate(function);
    value.call();
}

...
QFutureSynchronizer<void> synchronizer;

//Set the max pooled threads
QThreadPool::globalInstance()->setMaxThreadCount(THREADS);

//Start all threads and add them to the future synchronizer
for (int i = 0; i < THREADS; i++)
    synchronizer.addFuture(QtConcurrent::run(worker_function, QString("(function() {var r = Math.random(); while(1>0) print(r);})")));

//Wait for all threads to finish
synchronizer.waitForFinished();
...
Sign up to request clarification or add additional context in comments.

2 Comments

So basically, with both solutions, you create as many ScriptEngines, as you make function calls?
Yes, but if i'm correct it will share globalObject. However it's a guess, considering i'm novice in Qt Script. ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.