【发布时间】:2017-06-19 16:21:21
【问题描述】:
标准 C++11 是否保证 std::async(std::launch::async, func) 在单独的线程中启动函数?
工作草案,C++ 编程语言标准 2016-07-12:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4606.pdf
1.一方面,C++11-Standard说如果线程不能被创建,那么就会出错。这确保了新线程的创建(在没有错误的情况下)。
§ 30.6.8
6
抛出:system_error if policy == launch::async 和 实现无法启动新线程。
7 错误条件:
(7.1) — resource_unavailable_try_again — 如果 策略 == launch::async 并且系统无法启动新线程。
文档说:http://en.cppreference.com/w/cpp/thread/launch
std::launch::async 启动一个新线程来执行任务 异步
2。另一方面,据说可以潜在地创建线程。那些,不必创建线程。
§ 30.6.8
1 函数模板 async 提供了一种机制来启动 函数可能在一个新线程中并提供结果 在与其共享共享状态的未来对象中运行。
而且这里写成好像在一个新线程中,是不是意味着不需要在新的单独线程中?
§ 30.6.8
(3.1)
——如果 policy & launch::async 非零——调用 INVOKE (DECAY_COPY (std::forward(f)), DECAY_COPY (std::forward(args))...) (20.14.2, 30.3.1.2) 好像在一个新线程中 执行 由对 DECAY_COPY () 的调用的线程对象表示 在调用异步的线程中评估。存储任何返回值 作为共享状态的结果。从传播的任何异常 执行 INVOKE (DECAY_COPY (std::forward(f)), DECAY_COPY (std::forward(args))...) 作为异常结果存储在 共享状态。线程对象以共享状态存储,并且 影响任何引用的异步返回对象的行为 那个状态。
当使用 std::async(std::launch::async, func) 时,标准 C++11 是否保证 func() 将在单独的线程中执行,或者它可以在调用 async 的同一线程中执行?
【问题讨论】:
-
我读到“好像在一个新线程中”的意思是“好像你打电话给
std::thread(func)” -
我认为“好像”是指可观察到的行为就像您在一个新线程中一样。例如,线程局部变量将被初始化和销毁。
-
看起来并不保证会产生一个线程,但它看起来可以保证程序的行为就像你做的那样。它的措辞可能是为了进行一些巧妙的优化。
-
如果不需要线程怎么办,例如,如果使用 IO 完成端口?在所有语言中,
future或async功能允许应用程序启动异步操作并在返回时处理其结果。这并不意味着将使用一个线程,或者该线程将是一个新线程。对于真正的异步操作(通常是 IO),您可能根本不需要线程。如果实现使用线程池,您可能会从池中获得一个空闲线程,而不是启动一个新线程。 -
@Panagiotis Kanavos 是的,也许你是对的,如果它使用 IO 完成端口(Proactor 设计模式),它可以使用 OS/C++ 运行时线程池中已经创建的线程。但问题不是“是否会创建一个新线程”,而是“将在另一个线程中执行
func()而不是调用async()的线程”?那些,这是否保证我可以通过使用std::launch::async来加速我的程序,在if (std::thread::hardware_concurrency() >= 2)条件下占用两个可用的CPU 内核?
标签: c++ multithreading c++11 asynchronous c++14