c++ - Qt moveToThread() vs llamada nueva cadena cuando usamos cada
qthread exec (2)
¿Cuándo usamos cada una de estas llamadas de funciones en una aplicación con subprocesos? teniendo en cuenta dos funciones fun1 () y fun2 () definidas en la misma clase que tratan con la lectura / escritura de datos en búferes (operación de cola). para lograr multi-threading a estos. tendríamos que ejecutar las dos funciones en un hilo separado. ahora digamos que la primera lectura de la función se llama al comienzo de su hilo.
¿Es mejor usar moveTothread (segundo hilo) para escribir funciones al comienzo del primer hilo de funciones?
O
defina la segunda función en una nueva clase de subproceso y llame a esa cadena al comienzo del primer subproceso.
Al igual que Piotr respondió, realmente debería echarle un vistazo al enlace que sugirió.
Como entiendo su problema, eso debería resolver su problema.
Este es el código simplificado de ese 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();
}
Usando moveToThread
podemos cambiar la afinidad del hilo de un objeto. Lo que OP pregunta es cómo podemos ejecutar dos funciones de la misma clase en diferentes hilos.
Deje la clase A
y dos funciones f1
y f2
class A
{
public:
void f1();
void f2(int i);
void run(); // shows how we can trigger f1 and f2 in different threads
}
Qt
ya proporcionó una clase para ejecutar funciones en diferentes hilos y se llama QtConcurrentRun
La función
QtConcurrent::run()
ejecuta una función en un hilo separado. El valor de retorno de la función está disponible a través de la APIQFuture
.
La función que se activa puede ser una función externa o una función miembro. Entonces, en nuestro caso, si quisiéramos que el objeto en sí comenzara f1
y f2
en diferentes hilos, podríamos hacer lo siguiente en 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);
}
de forma similar, podría ejecutar cualquier función pública de cualquier clase al mismo tiempo, por ejemplo
QImage image = ...;
QFuture<void> future = QtConcurrent::run(image, &QImage::invertPixels, QImage::InvertRgba);
A a;
QFuture<void> future1 = QtConcurrent::run(A, &A::f1);
Observe la diferencia entre las dos llamadas:
QtConcurrent::run()
también acepta punteros a funciones miembro. El primer argumento debe ser una referencia constante o un puntero a una instancia de la clase. Pasar por referencia de referencia es útil cuando se llaman funciones miembro de const; pasar por el puntero es útil para llamar a funciones miembro no constantes que modifican la instancia.
Para verificar cuándo ha finalizado una función ejecutada simultáneamente, debe usar QFutureWatcher
.