我一直在考虑std::async
以及如何在未来的编译器实现中使用它。然而,现在我有点被一些感觉像是设计缺陷的东西所困扰。
std::async
非常依赖于实现,可能有 launch::async
的两个变体,一种将任务启动到新线程中,另一种使用线程池/任务调度程序。
但是,这取决于用于实现 std::async
的变体中的哪一种, 用法会有很大差异。
对于基于“线程池”的变体,您可以启动许多小任务而不必担心开销,但是,如果其中一个任务在某个时候阻塞怎么办?
另一方面,“启动新线程”变体不会遇到阻塞任务的问题,另一方面,启动和执行任务的开销会非常高。
线程池: +低开销,-从不阻塞
启动新线程: +fine with blocks,-高开销
所以基本上取决于实现,我们使用的方式std::async
会非常警惕。如果我们有一个程序可以很好地与一个编译器一起工作,那么它可能在另一个编译器上工作得非常糟糕。
这是设计使然吗?还是我错过了什么?你会像我一样认为这是一个大问题吗?
在当前规范中,我缺少 std::oversubscribe(bool)
之类的内容为了启用独立于实现的使用 std::async
.
编辑:据我所知,C++11 标准文档没有给出关于任务是否发送到 std::async
的任何提示。可以阻止也可以不阻止。
最佳答案
std::async
使用 std::launch::async
策略启动的任务“就像在新线程中一样”运行,因此线程池并不是真正的支持 --- 运行时必须在每个任务执行之间拆除并重新创建所有线程局部变量,这并不简单。
这也意味着您可以期望以 std::launch::async
策略启动的任务同时运行。可能会有启动延迟,如果您的运行线程多于处理器,则会出现任务切换,但它们应该正在运行,而不是因为一个碰巧等待另一个而死锁。
实现可以选择提供扩展,允许您的任务在线程池中运行,在这种情况下,由该实现来记录语义。
关于c++ - std::async - 依赖于实现的用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9363377/