EffectiveModernCppChinese/item37.md at master · dbdxnuliba/EffectiveModernCppChinese · GitHub

您所在的位置:网站首页 std::ofstream阻塞 EffectiveModernCppChinese/item37.md at master · dbdxnuliba/EffectiveModernCppChinese · GitHub

EffectiveModernCppChinese/item37.md at master · dbdxnuliba/EffectiveModernCppChinese · GitHub

2023-04-03 03:34| 来源: 网络整理| 查看: 265

条款三十七:使std::thread在所有路径最后都不可结合

Item 37: Make std::threads unjoinable on all paths

每个std::thread对象处于两个状态之一:可结合的(joinable)或者不可结合的(unjoinable)。可结合状态的std::thread对应于正在运行或者可能要运行的异步执行线程。比如,对应于一个阻塞的(blocked)或者等待调度的线程的std::thread是可结合的,对应于运行结束的线程的std::thread也可以认为是可结合的。

不可结合的std::thread正如所期待:一个不是可结合状态的std::thread。不可结合的std::thread对象包括:

默认构造的std::threads。这种std::thread没有函数执行,因此没有对应到底层执行线程上。 已经被移动走的std::thread对象。移动的结果就是一个std::thread原来对应的执行线程现在对应于另一个std::thread。 已经被join的std::thread 。在join之后,std::thread不再对应于已经运行完了的执行线程。 已经被detach的std::thread 。detach断开了std::thread对象与执行线程之间的连接。

(译者注:std::thread可以视作状态保存的对象,保存的状态可能也包括可调用对象,有没有具体的线程承载就是有没有连接)

std::thread的可结合性如此重要的原因之一就是当可结合的线程的析构函数被调用,程序执行会终止。比如,假定有一个函数doWork,使用一个过滤函数filter,一个最大值maxVal作为形参。doWork检查是否满足计算所需的条件,然后使用在0到maxVal之间的通过过滤器的所有值进行计算。如果进行过滤非常耗时,并且确定doWork条件是否满足也很耗时,则将两件事并发计算是很合理的。

我们希望为此采用基于任务的设计(参见Item35),但是假设我们希望设置做过滤的线程的优先级。Item35阐释了那需要线程的原生句柄,只能通过std::thread的API来完成;基于任务的API(比如future)做不到。所以最终采用基于线程而不是基于任务。

我们可能写出以下代码:

代码如下:

constexpr auto tenMillion = 10000000; //constexpr见条款15 bool doWork(std::function filter, //返回计算是否执行; int maxVal = tenMillion) //std::function见条款2 { std::vector goodVals; //满足filter的值 std::thread t([&filter, maxVal, &goodVals] //填充goodVals { for (auto i = 0; i bool doWork(std::function filter, //同之前一样 int maxVal = tenMillion) { std::vector goodVals; //同之前一样 ThreadRAII t( //使用RAII对象 std::thread([&filter, maxVal, &goodVals] { for (auto i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3