When do we use each of this function calls in a threaded application. given two functions fun1() and fun2() defined in the same class dealing with read/write of data into buffers(queue operation). to achieve multi-threading to these. we would have to run the two functions in a separate thread. now lets say the first function read is called at the start of its thread.
is it better to use moveTothread ( second thread)for function write at the start of the first functions thread
Or
define the second function in a new thread class and call that thread at the start of the first thread.
moveToThread() is used to control the object's thread affinity, which basically means setting the thread (or better the Qt event loop) from which the object will emit signals and its slots will be executed.
To use it, prepare a QObject subclass with all your desired functionality in it. Then create a new QThread instance, push the QObject onto it using moveToThread(QThread*) of the QObject instance and call start() on the QThread instance. That's all.
A QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread. You can use worker objects by moving them to the thread using QObject::moveToThread().
QThread::wait() is just a convenience function that waits until QThread ceases to execute. It will work both with exit() and terminate() .
Like Piotr answered you should really have a look at the link he suggested.
As I understand your problem, that should solve your problem.
This is the simplified code from that blog:
class Producer
{
public:
Producer();
public slots:
void produce()
{ //do whatever to retrieve the data
//and then emit a produced signal with the data
emit produced(data);
//if no more data, emit a finished signal
emit finished();
}
signals:
void produced(QByteArray *data);
void finished();
};
class Consumer
{
public:
Consumer();
public slots:
void consume(QByteArray *data)
{
//process that data
//when finished processing emit a consumed signal
emit consumed();
//if no data left in queue emit finished
emit finished();
}
};
int main(...)
{
QCoreApplication app(...);
Producer producer;
Consumer consumer;
producer.connect(&consumer, SIGNAL(consumed()), SLOT(produce()));
consumer.connect(&producer, SIGNAL(produced(QByteArray *)), SLOT(consume(QByteArray *));
QThread producerThread;
QThread consumerThread;
producer.moveToThread(&producerThread);
consumer.moveToThread(&consumerThread);
//when producer thread is started, start to produce
producer.connect(&producerThread, SIGNAL(started()), SLOT(produce()));
//when consumer and producer are finished, stop the threads
consumerThread.connect(&consumer, SIGNAL(finished()), SLOT(quit()));
producerThread.connect(&producer, SIGNAL(finished()), SLOT(quit()));
producerThread.start();
consumerThread.start();
return app.exec();
}
Using moveToThread
we can change the thread affinity of an object. What the OP asks is how we can run two functions of the same class in different threads.
Let class A
and two functions f1
and f2
class A
{
public:
void f1();
void f2(int i);
void run(); // shows how we can trigger f1 and f2 in different threads
}
Qt
already provided a class for running functions in different threads and it is called QtConcurrentRun
The
QtConcurrent::run()
function runs a function in a separate thread. The return value of the function is made available through theQFuture
API.
The function that is triggered can be either an external function or a member function. So in our case if we wanted from the object itself to start f1
and f2
in different threads we could do the following in run()
void run()
{
// QFuture<void> because f1 is void
QFuture<void> future1 = QtConcurrent::run(this, &A::f1);
int k = 5; // Concurrent run with arguments
QFuture<void> future2 = QtConcurrent::run(this, &A::f2, k);
}
similarly you could execute any public function of any class concurrently, eg
QImage image = ...;
QFuture<void> future = QtConcurrent::run(image, &QImage::invertPixels, QImage::InvertRgba);
A a;
QFuture<void> future1 = QtConcurrent::run(A, &A::f1);
Notice the difference between the two calls:
QtConcurrent::run()
also accepts pointers to member functions. The first argument must be either a const reference or a pointer to an instance of the class. Passing by const reference is useful when calling const member functions; passing by pointer is useful for calling non-const member functions that modify the instance.
In order to check when a concurrently executed function has finished you should use a QFutureWatcher
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With