gpt4 book ai didi

c++ - QtConcurrent::blockingMap 与 QtConcurrent::map 和 waitForFinished

转载 作者:行者123 更新时间:2023-11-30 02:17:12 27 4
gpt4 key购买 nike

Qt 文档说明了以下关于 QtConcurrent::blockingMap 的内容:

Note: This function will block until all items in the sequence have been processed.

QtConcurrent::map 的文档在其他方面是相同的。它还返回 QFuture<void>而不是 void .

QFuture 的文档有以下评论:

The waitForFinished() function causes the calling thread to block and wait for the computation to finish, ensuring that all results are available.

因此,我预计 QtConcurrent::blockingMap(seq, f)QtConcurrent::map(seq, f).waitForFinished() 相同.然而,事实并非如此。

#include <QObject>
#include <QtConcurrent>

class Foo : public QObject {
Q_OBJECT
public:
explicit Foo(QObject *parent = nullptr) : QObject(parent) {
connect(this, &Foo::signal, this, &Foo::slot, Qt::AutoConnection);
}

void startMapWithWaiting() {
qDebug("startMapWithWaiting");
slot_counter = 0;
std::atomic_int signal_counter = 0;
QtConcurrent::map(nums, [&](auto &&num) {
++signal_counter;
emit signal();
}).waitForFinished();
qDebug("result: %d signals, %d slots", int(signal_counter), int(slot_counter));
slot_counter = 0;
}

void startBlockingMap() {
qDebug("startBlockingMap");
slot_counter = 0;
std::atomic_int signal_counter = 0;
QtConcurrent::blockingMap(nums, [&](auto &&num) {
++signal_counter;
emit signal();
});
qDebug("result: %d signals, %d slots", int(signal_counter), int(slot_counter));
slot_counter = 0;
}

public slots:
void slot() { ++slot_counter; }

signals:

void signal();

private:
std::atomic_int slot_counter = 0;
std::vector<int> nums{1, 2, 5, 8};
};

#include "main.moc"

int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
Foo *foo = new Foo(&app);
QTimer::singleShot(10, foo, [foo, &app]() {
foo->startMapWithWaiting();
foo->startBlockingMap();
app.quit();
});
return app.exec();
}

输出是

startMapWithWaiting
result: 4 signals, 4 slots
startBlockingMap
result: 4 signals, x slots

在哪里x从 0 到 4 不等,具体取决于……某事。这令人困惑。

我想知道这两种方式有什么区别,我是如何误读文档的。

最佳答案

这两种方法的工作方式相同:所有 lambda 函数都在发出 4 个信号时终止。示例中调用的插槽的不同取决于 emit signal() 的工作方式。由于程序使用 Qt::AutoConnection 作为信号/槽:

  • 如果目标线程(创建Foo的主线程)与当前线程(池线程,由全局ThreadPool控制)不相同,事件将被放入事件队列,否则,槽直接执行(与Qt::DirectConnection相同)。

使用相同的示例可以得到不同的结果(x 个插槽)。这取决于全局线程池如何管理它的线程。在我的配置中,输出是:

    startMapWithWaiting
result : 4 signals, 0 slots
startBlockingMap
result : 4 signals, 4 slots

要获得相同的结果,我们可以使用 Qt::DirectConnection 代替 Qt::AutoConnection 或在打印结果之前调整 QApplication::processEvent() :

    QApplication::processEvents(); //<-- force slot() to be processed.
qDebug("result blocking : %d signals, %d slots", int(signal_counter), int(slot_counter));

关于c++ - QtConcurrent::blockingMap 与 QtConcurrent::map 和 waitForFinished,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53978796/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com