Qt moveToThread()vs我们使用每个时调用新线程

时间:2011-03-01 09:29:12

标签: c++ multithreading qt qthread

我们何时在线程应用程序中使用每个函数调用。 给定两个函数fun1()和fun2()在同一个类中定义处理数据读/写缓冲区(队列操作)。实现对这些的多线程。我们必须在一个单独的线程中运行这两个函数。现在假设第一个函数read在其线程的开头被调用。

  

使用moveTothread(第二个线程)更好吗?   函数写在第一个开头   函数线程

  

在新的中定义第二个函数   线程类并调用该线程   第一个帖子的开头。

2 个答案:

答案 0 :(得分:9)

像Piotr回答的那样,你应该看看他建议的链接 据我了解你的问题,这应该可以解决你的问题 这是该博客的简化代码:

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

答案 1 :(得分:8)

使用moveToThread我们可以更改对象的线程亲和力。 OP问的是我们如何在不同的线程中运行同一个类的两个函数。

让课程A和两个职能f1f2

class A
{
public:
    void f1();
    void f2(int i); 
    void run(); // shows how we can trigger f1 and f2 in different threads
}

Qt已经提供了一个在不同线程中运行函数的类,它被称为QtConcurrentRun

  

QtConcurrent::run()函数在单独的线程中运行函数。   函数的返回值可通过QFuture获得   API。

触发的功能可以是外部功能,也可以是成员功能。因此,在我们的情况下,如果我们希望从对象本身在不同的线程中启动f1f2,我们可以在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);
} 

类似地,您可以同时执行任何类的任何公共函数,例如

QImage image = ...;
QFuture<void> future = QtConcurrent::run(image, &QImage::invertPixels, QImage::InvertRgba);

A a;
QFuture<void> future1 = QtConcurrent::run(A, &A::f1);

注意两个电话之间的区别:

  

QtConcurrent::run()也接受指向成员函数的指针。该   第一个参数必须是const引用或指向的引用   班级的实例。传递const引用非常有用   调用const成员函数;通过指针传递是有用的   调用修改实例的非const成员函数。

为了检查同时执行的功能何时结束,您应该使用QFutureWatcher