2017-04-24 6 views
1

여러 (최대 50 개 이상)의 Qt 스크립트 기능을 동시에 실행해야합니다. 스크립트 함수로 2 ~ 3 개의 스레드를 돌리는 것은 정상적으로 작동하지만, 약 50 개의 스레드를 실행하자마자 오류가 발생하고 프로그램이 중단됩니다.Qt 스크립트 멀티 쓰레드

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

내 MAIN.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(); 
} 

: 이것은 내 threadworker.cpp이

#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 

입니다 : 이것은 내 threadworker.h는

#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(); 
} 

입니다 나는 금액과는 독립적으로 Qt Script Threads는 정상적으로 실행되며이 반대로 동작하는 원인을 이해할 수 없습니다. 그것은 도전이 너무 많은 스레드를 생성하고 응용 프로그램 종료에 적절하게 발표 할 예정이다,

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

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

private: 
    QScriptEngine engine; 
    QScriptValue value; 
}; 

을하지만 :

+0

main()에 스레드를 만들고 main()의 해당 스레드로 객체를 이동하려고 했습니까? – ni1ight

+0

@ ni1ight 님이 시도했습니다. 아무것도 바뀌지 않습니다. 여전히 같은 문제. – Korboh

답변

0

노동자 클래스에 QScriptEngine 퍼팅과 작업자 스레드에 moveToThread 이동을하자, 해결하는 것 . 풀링 된 스레드를 사용하는 것이 좋습니다 (예 : QtConcurrent). QtConcurrent은 클래스가 아니라 함수 만있는 다중 스레드를 허용하며, QFutureSyncronyzer을 사용하면 마무리 할 모든 스레드를 한 번만 기다릴 수 있습니다. 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(); 
... 
+0

기본적으로 두 솔루션 모두에서 함수 호출을 할 때만큼 많은 ScriptEngine을 만들 수 있습니까? – Korboh

+0

네,하지만 맞으면'globalObject'를 공유 할 것입니다. 그러나 나는 그것이 Qt Script의 초심자 인 것을 감안할 때 추측이다. ;) –