【问题标题】:Qt moveToThread() vs calling new thread when do we use eachQt moveToThread() vs 调用新线程我们什么时候使用每个
【发布时间】:2011-07-06 08:58:34
【问题描述】:

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

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

或者

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

【问题讨论】:

标签: c++ multithreading qt qthread


【解决方案1】:

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

【讨论】:

  • 这是我试图解决的问题的完美参考。不错的惯用 Qt 方法。我所做的唯一修改是将consumed() 信号与produce() 插槽分离,并将生产者的finished() 信号与消费者的finished() 信号连接起来。这样生产者就不会等待消费者,并在可以安全退出时通知消费者。
【解决方案2】:

使用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 成员函数;通过指针传递对 调用修改实例的非常量成员函数。

为了检查并发执行的函数何时完成,您应该使用QFutureWatcher

【讨论】:

    猜你喜欢
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-11
    • 2011-03-11
    相关资源
    最近更新 更多