std :: async - 依赖于实现的用法?

时间:2012-02-20 15:12:27

标签: c++ c++11 stdasync

我一直在考虑std::async以及如何在将来的编译器实现中使用它。但是,现在我有点卡在一些感觉像设计缺陷的东西上。

std::async几乎与实现有关,可能有两个launch::async变体,一个将任务启动到新线程,另一个使用线程池/任务调度程序。

但是,根据用于实现std::async的其中一个变体,使用情况会有很大差异。

对于基于“线程池”的变体,您可以启动许多小任务而不必担心开销,但是,如果其中一个任务在某些时候阻塞了怎么办?

另一方面,“启动新线程”变体不会遇到阻塞任务的问题,另一方面,启动和执行任务的开销会非常高。

线程池: +低开销,永远阻止

推出新主题 +很好的块,高开销

所以基本上取决于实现,我们使用std::async的方式会非常谨慎。如果我们有一个适用于一个编译器的程序,那么它可能会在另一个编译器上运行得很糟糕。

这是设计的吗?或者我错过了什么?像我一样,你会认为这是一个大问题吗?

在当前规范中,我遗漏了std::oversubscribe(bool)之类的内容,以便能够实现std::async的依赖用法。

编辑:据我所知,C ++ 11标准文档没有提供有关发送到std::async的任务是否可能阻止的任何提示。

2 个答案:

答案 0 :(得分:11)

使用std::async运行的策略启动的

std::launch::async任务,就像在新线程中一样“,因​​此不支持线程池 - 运行时必须拆除并重新创建所有每个任务执行之间的线程局部变量,这不是直截了当的。

这也意味着您可以预期以std::launch::async策略启动的任务可以同时运行。可能存在启动延迟,如果你有比运行处理器更多的运行线程,那么将会有任务切换,但它们应该正在运行,而不是因为一个人正在等待另一个而死锁。

实现可以选择提供扩展,允许您的任务在线程池中运行,在这种情况下,由该实现来记录语义。

答案 1 :(得分:1)

我希望实现能够启动新线程,并将线程池留给将其标准化的C ++的未来版本。有没有使用线程池的实现?


MSVC最初使用基于其并发运行时的线程池。根据{{​​3}},这已被删除。 C ++规范为实现者留下了一些空间来做聪明的事情,但是我认为它没有为这个线程池实现留下足够的空间。特别是我认为规范仍然需要销毁和重建thread_local个对象,但是使用ConcRT的那个线程池不会支持它。