Qt Quick in High demand environment
-
I am making an easy and fool test to be sure we can use Qt Quick on our High Demand scenario.
In our environment, a QML can receive a lot of signals in a little slot from non QT Threads, so I created a test application:class FakeQML: public QObject { Q_OBJECT public: FakeQML(QObject *parent = nullptr); Q_INVOKABLE void start(); signals: void fakeSignal(); }; FakeQML::FakeQML(QObject *parent): QObject(parent){} void FakeQML::start(){ std::thread *signalEmisor = new std::thread([this](){ while(true) fakeSignal(); }); } Test.FakeQML{ onFakeSignal: console.log("onFakeSignal"); Component.onCompleted: start(); }
This, of course, is "crashing" as the memory of my application never stop to grow and SO decides to kill it (checked in Linux, Windows and MAC).
I can assume that as an expected behaviour but I would like to find any example or Qt guide documentation with some useful technical(based in Qt) to resolved this situation.
Many thanks. -
Resolve which situation?
First check your implementation for sanity.You are allocating memory until your system can then crash.
Why you even bothered with std::thread, Qt or QML.
You could do the same with two lines:while( true )
new int; -
I am making an easy and fool test to be sure we can use Qt Quick on our High Demand scenario.
Your test shows only that you can flood the event loop if you put yourself into it. What is it you're trying to test, and what's the purpose of this endless emission of signals? It looks you have a classic producer-consumer problem, and you're producing at a rate much higher than the consumption happens, so naturally this causes your application to just eat up all the memory and eventually die.
-
I am making an easy and fool test to be sure we can use Qt Quick on our High Demand scenario.
Your test shows only that you can flood the event loop if you put yourself into it. What is it you're trying to test, and what's the purpose of this endless emission of signals? It looks you have a classic producer-consumer problem, and you're producing at a rate much higher than the consumption happens, so naturally this causes your application to just eat up all the memory and eventually die.
@kshegunov yes, that is exactly the problem I am trying to manage. I am sending a lot of remote data via C++ and that data has to be handled in QML layer. I know producer-consumer concepts but I am not able to find any doc/example to sincronize C++ and QML layer on a "Qt way" beyond of doing it manually. Is there any Qt class or QT recomendation to resolve this? I have this "issue" fixed in my code, but I would like to use Qt Stack in case of they provide a mechanism for this.
-
Resolve which situation?
First check your implementation for sanity.You are allocating memory until your system can then crash.
Why you even bothered with std::thread, Qt or QML.
You could do the same with two lines:while( true )
new int;@alex_malyu the correct question is Is there a "Qt way" to resolve producer-consumer situations? I am receiving a lot of remote data via C++ and I have to poulate it to QML layer.
-
@kshegunov yes, that is exactly the problem I am trying to manage. I am sending a lot of remote data via C++ and that data has to be handled in QML layer. I know producer-consumer concepts but I am not able to find any doc/example to sincronize C++ and QML layer on a "Qt way" beyond of doing it manually. Is there any Qt class or QT recomendation to resolve this? I have this "issue" fixed in my code, but I would like to use Qt Stack in case of they provide a mechanism for this.
@miguelorenes
I think you're confusing the concepts. This is a thread synchronization problem and not a C++ - QML incompatibility. In the end QML will just be parsed by and operate upon C++ objects. So your question boils down to how to not overflow a queue. Well, the simplest way is to block the producer at some point if it has exceeded the allowed number of generated events. Consider this very simplistic example:class FakeQML: public QObject { Q_OBJECT public: Q_INVOKABLE void start(); signals: void fakeSignal(); void dataAvailable(); private slots: void processSignal(); private: QSemaphore signalsSync; }; void FakeQML::start() { signalsSync.release(100); // Queue up to 100 signal-slot invocations QObject::connect(this, SIGNAL(fakeSignal()), this, SLOT(processSignal())); std::thread *signalEmisor = new std::thread([this]() { while(true) { signalsSync.acquire(); // Blocks if there are no free resources fakeSignal(); } }); } void FakeQML::processSignal() { // Do something to process the signal // ... // Tell the producer we have done that and it can produce us more work signalSync.release(); // Signal QML we have processed a chunk of data (optional): emit dataAvailable(); }
-
@alex_malyu the correct question is Is there a "Qt way" to resolve producer-consumer situations? I am receiving a lot of remote data via C++ and I have to poulate it to QML layer.
This post is deleted! -
@miguelorenes
I think you're confusing the concepts. This is a thread synchronization problem and not a C++ - QML incompatibility. In the end QML will just be parsed by and operate upon C++ objects. So your question boils down to how to not overflow a queue. Well, the simplest way is to block the producer at some point if it has exceeded the allowed number of generated events. Consider this very simplistic example:class FakeQML: public QObject { Q_OBJECT public: Q_INVOKABLE void start(); signals: void fakeSignal(); void dataAvailable(); private slots: void processSignal(); private: QSemaphore signalsSync; }; void FakeQML::start() { signalsSync.release(100); // Queue up to 100 signal-slot invocations QObject::connect(this, SIGNAL(fakeSignal()), this, SLOT(processSignal())); std::thread *signalEmisor = new std::thread([this]() { while(true) { signalsSync.acquire(); // Blocks if there are no free resources fakeSignal(); } }); } void FakeQML::processSignal() { // Do something to process the signal // ... // Tell the producer we have done that and it can produce us more work signalSync.release(); // Signal QML we have processed a chunk of data (optional): emit dataAvailable(); }
@kshegunov many thanks for your answers. I consider your example. I am finishing to aboard the issue I am having and to be honest, my producer thread in my application is not collapsing QML layer(I checked Memory and CPU % and it is not growing), the actual problem I was having is a "memory stomp" when emiting some signal but, as I can imagine you know this kind of issues sometimes are really dificil to isolate.
I accept you answer as you correctly resolved the post.
Cheers.