通过连接QObject

时间:2017-11-16 20:22:29

标签: c++ multithreading qt c++11

我有一些使用std::future / std::promise的现有代码,我想要干净地与Qt GUI集成。

理想情况下,人们可以:

std::future<int> future{do_something()};
connect(future, this, &MyObject::resultOfFuture);

然后将resultOfFuture实现为一个获取一个参数的插槽:来自int的{​​{1}}值。我已将此建议添加为对QTBUG-50676的评论。我最喜欢这个,因为我的大部分未来/承诺都不是并发的,所以我想避免激活一个线程只是为了等待它们。此外,类型推断可以在future和slot的参数之间起作用。

但在我看来,使用包装器Qt对象(例如std::future<int>版本需要QFutureWatcher)并不难实现。包装器的两个问题是:

  1. 包装器必须在其结果类型中具体。
  2. 观察者必须在一个线程中并发?
  3. 是否有实施此类连接的最佳做法?还有另一种方法可以挂钩到Qt主循环并避免创建线程吗?

1 个答案:

答案 0 :(得分:1)

std::future缺少延续。将std::future的结果异步转换为提供结果的函数调用的唯一方法是启动一个线程来观察它,如果你想避免忙碌等待,你需要一个这样的线程每std::future ,因为没有办法懒惰等待多个future s。

有计划创建一个具有延续的未来(then操作),但从开始,它们不在C ++中,更不用说

您可以编写自己的未来/承诺系统,模仿支持延续的std::futurestd::promise的界面,或找到已经完成此操作的库。

定期检查未来是否准备就绪的忙等待解决方案可以避免启动新线程。

无论如何,std::experimental::then会让您的问题变得微不足道。

future.then( [some_state](auto future){
  try {
    auto x = future.get();
    // send message with x
  } catch( ... ) {
    // deal with exception
  }
} );

您可以编写自己的std::experimetnal::future或查找要自行使用的实现,但如果不使用带有std::future的额外线程,则无法提供此功能