c++ - Starting processes in threads as spawned -
i have problem looking create processing class, , want feed data it, put thread, , tell start working. currently, have that:
processingclass *worker = new processingclass(mydata); connect(this, signal(startworking()), worker, slot(startworking())); connect(worker, signal(doneworking(data)), this, slot(workerfinished(data))); qthread *workerthread = new qthread; worker->movetothread(workerthread); workerthread->start(); emit(startworking());
what ends doing creates worker, gives data want process, connects needs connected work, moves on over thread, , emits signal start working. more or less want to, there issue. namely, want putting loop:
while (reason){ ...//gathering data give worker processingclass *worker = new processingclass(mydata); connect(this, signal(startworking()), worker, slot(startworking())); connect(worker, signal(doneworking(data)), this, slot(workerfinished(data))); qthread *workerthread = new qthread; worker->movetothread(workerthread); workerthread->start(); } emit(startworking());
this accomplish want do, sticking in memory, waiting until there, , set off every single thread simultaneously compete resources until done. considering current data amount on 1000 different threads, each of takes (from previous iterations of program) ~1-2 minutes process information, , last version crashed because ran out of memory (i think...) don't particularly method anymore.
what figure out way move resources want thread, , set off thread work immediately. want able pause loop after amount of threads running (so not overload computer again) , continue loop , set off next thread after 1 of previous threads done.
is there nicer way accomplish this?
you should have fixed number of worker threads, , iterate loop when there threads not busy.
if insist on using qobject
, can create qrunnable
wrapper run worker objects until completion in thread pool, , track progress issue more work:
class processingrunnable : public processingclass, public qrunnable { void run() q_decl_override { qeventloop loop; movetothread(qthread::currentthread()); qmetaobject::invokemethod(this, "startworking", qt::queuedconnection); loop.exec(); movetothread(0); } public: explicit processingrunnable(const data & data) : processingclass(data) { setautodelete(false); movetothread(0); // moved worker thread later } }; class jobmanager : public qobject { q_object qthreadpool m_pool; qscopedpointer<processingrunnable> m_worker; int m_jobs; public: q_signal void alljobsfinished(); q_slot void runjobs() { while (true) { if (m_worker) { if (m_pool.trystart(m_worker.data()) m_worker.take(); else break; } } if (! reason) break; ... // gather data give worker m_worker.reset(new processingrunnable(mydata)); ++ m_jobs; connect(m_worker, &processingrunnable::doneworking, [this]{ -- m_jobs; runjobs(); if (! m_jobs) emit alljobsfinished(); }); } } explicit jobmanager(qobject * parent = 0) : qobject(parent), m_jobs(0) { } } int main(int argc, char ** argv) { qcoreapplication app(argc, argv); ... jobmanager manager; qobject::connect(&manager, &jobmanger::alljobsfinished, &app, &qcoreapplication::quit, qt::queuedconnection); manager.runjobs(); ... return app.exec(); }
for kind of application, might simpler make processingclass
simple functor, not qobject
, , use qtconcurrent::run
, qfuturewatcher
.
Comments
Post a Comment