它与 在 C + + 11中是否有 std: : 线程池?这个问题有着松散的联系。尽管这个问题不同,但意图是一样的:
问题1: 使用自己的(或第三方库)线程池来避免昂贵的线程创建是否仍然有意义?
另一个问题得出的结论是,不能依赖 std::thread
进行汇集(可能是,也可能不是)。然而,std::async(launch::async)
似乎有更高的机会被汇集。
它不认为它是被标准强制的,但是恕我直言,如果线程创建缓慢,那么所有好的 C + + 11实现都会使用线程池。只有在创建新线程成本较低的平台上,我认为它们总是会产生新线程。
问题2: 这只是我的想法,但我没有事实可以证明。我可能搞错了。这是有根据的猜测吗?
最后,这里我提供了一些示例代码,首先展示了我认为线程创建可以用 async(launch::async)
表示:
例子一:
thread t([]{ f(); });
// ...
t.join();
变成了
auto future = async(launch::async, []{ f(); });
// ...
future.wait();
例2: 放弃线程
thread([]{ f(); }).detach();
变成了
// a bit clumsy...
auto dummy = async(launch::async, []{ f(); });
// ... but I hope soon it can be simplified to
async(launch::async, []{ f(); });
问题3: 与 thread
版本相比,您更喜欢 async
版本吗?
剩下的不再是问题的一部分,而只是为了澄清:
为什么必须将返回值赋给一个虚拟变量?
不幸的是,当前的 C + + 11标准强制您捕获 std::async
的返回值,否则将执行析构函数,该函数将阻塞直到操作结束。有些人认为这是标准中的一个错误(例如,由 Herb Sutter 提出)。
Cppreference.com的这个例子很好地说明了这一点:
{
std::async(std::launch::async, []{ f(); });
std::async(std::launch::async, []{ g(); }); // does not run until f() completes
}
另一项澄清是:
我知道那个 线程池可能有其他合法的用途,但在这个问题中,我只对避免昂贵的线程创建成本感兴趣。
我认为仍然存在线程池非常有用的情况,特别是在需要对资源进行更多控制的情况下。 例如,服务器可能决定只同时处理固定数量的请求,以保证快速响应时间并增加内存使用的可预测性。线程池应该没问题。
线程局部变量可能也是您自己的线程池的一个参数,但我不确定它是否与实践有关:
std::thread
创建一个新线程不需要初始化线程本地变量。async
产生的线程中,对我来说有些不清楚,因为线程可能已经被重用了。根据我的理解,线程局部变量不一定会被重置,但是我可能弄错了。