gpt4 book ai didi

c++ - 为阻塞调用构造信号/槽包装器的正确方法是什么?

转载 作者:行者123 更新时间:2023-11-30 01:46:52 25 4
gpt4 key购买 nike

假设我有一个 QObject 和一个阻塞方法(比如说,这是一个库调用,需要在返回之前从网络中获取大量数据)。

class Foo : public QObject { 
Bar* _bar;
public:
// non blocking call, emits stuffDone when done
void startStuff(int a, int b);
signals:
void stuffDone(int sum);
}


class Bar {
public:
// Blocking call
int doStuff(int a, b) {
for(int i=0; i<=100000000000; i++);
return a + b;
}
}

我希望我的 Foo::startStuff 方法在适当的(单独的)线程中运行 doStuff 并触发 stuffDone 信号完成。startStuff 必须立即返回。

Bar 如果需要,可以是一个 QObject,从而允许通过 moveToThread

设置线程关联

这样做的最简单和最惯用的('Qt-like')方法是什么?

最佳答案

QtConcurrent::run 可能是最惯用的:

struct Bar {
// Blocks for 3 seconds
int doStuff(int a, b) {
QThread::sleep(3);
return a+b+42;
}
};

class Foo : public QObject {
Q_OBJECT
Bar _bar;
public:
// Non-blocking, emits stuffDone when done
void startStuff(int a, int b) {
QtConcurrent::run([a,b,this]{
auto result = _bar.doStuff(a,b);
emit stuffDone(result);
});
}
Q_SIGNAL void stuffDone(int sum);
};

除了使用自定义的 Foo 类,您还可以使用 QFutureWatcher,但恕我直言,它更麻烦,因为没有提供结果的信号 - 您需要连接一个作用于结果的仿函数。

QSharedPointer<Bar> bar { new Bar };
auto watcher = new QFutureWatcher<int>;
connect(watcher, &QFutureWatcher::finished, watcher, [watcher, bar]{
watcher->deleteLater();
int result = watcher->result();
// use the result here
});
auto future = QtConcurrent::run(&Bar::doStuff, bar, 1, 2);
watcher->setFuture(future);

请注意,“长”加法循环通常会被优化掉,因为它没有副作用,因此是死代码。如果你想模拟阻塞,使用QThread::[|m|u]sleep

关于c++ - 为阻塞调用构造信号/槽包装器的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32507937/

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