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.
Putting the
QScriptEngineon worker class and letmoveToThreadmove it to the the worker thread, seems to solve: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.QtConcurrentallows you (for example but not limited to) multithread with just functions, not necessarly classes, and withQFutureSyncronyzeryou can in one call wait for all the threads you want to finish. SeeQtConcurrent: