1 /* 2 * 话题1:基于“转移线程的所有权”,改进 thread_guard 类, 确保 std::thread 可以被 join或detach。 3 * 类 Scoped_thread 的构造函数把参数传递的 std::thread 拥有的所有权转移到自身成员变量上。 4 * 如果参数传递的 std::thread 在传递之前进行过 join或detach 则会抛出逻辑异常。 5 * 6 * 话题2:对比 thread_guard 类和 scoped_thread 类 7 * 在 thread_guard 类中,只是保存了 std::thread& 一份引用。如果构造函数传递进来的 std::thread 8 * 已经被不合理的 join或detach过,则 thread_guard 毫无用处,反倒会迷惑的开发人员。而 scoped_thread 9 * 不会接受这样的事情发生,只要传递给 scoped_thread的参数不合理,就直接抛出了逻辑异常,开发人员可以很 10 * 清晰的知道自己犯了错误。 11 * 12 * 话题3:转移线程的应用场景 13 * 使用 std::vector 批量管理线程 14 * 15 * 16 * 小条儿1: std::forward 17 * 18 * 小条儿2: std::men_fn 与 for_each 19 * 20 * 21 * 回顾和思考-1:构造函数的初始化列表和函数体的执行顺序是什么,如何证明? 22 */
1 /* 话题1:基于“转移线程的所有权”,改进 thread_guard 类, 确保 std::thread 可以被 join或detach。 2 * 类 Scoped_thread 的构造函数把参数传递的 std::thread 拥有的所有权转移到自身成员变量上。 3 * 如果参数传递的 std::thread 在传递之前进行过 join或detach 则会抛出逻辑异常。 4 */
1 class Scoped_thread{ 2 std::thread m_t; 3 public: 4 Scoped_thread(std::thread t): 5 m_t(std::move(t)) 6 { 7 if (!m_t.joinable()) 8 throw std::logic_error("No thread"); 9 } 10 ~Scoped_thread(){ 11 m_t.join(); 12 } 13 Scoped_thread(const Scoped_thread &) = delete; 14 Scoped_thread& operator=(const Scoped_thread &) = delete; 15 }; 16 17 void func(){ 18 std::cout<<"hello word"<<std::endl; 19 } 20 void func1(){ 21 std::cout<<"hello word1"<<std::endl; 22 } 23 void func2(){ 24 std::cout<<"hello word2"<<std::endl; 25 } 26 27 int main(int argc, char *argv[]) 28 { 29 QCoreApplication a(argc, argv); 30 31 std::thread t(func); 32 //t.join(); //不再需要,由 Scoped_thread 对象负责 33 Scoped_thread s(std::move(t)); 34 Scoped_thread ss(std::thread(func1)); //warn: C4930:"Scoped_thread ss(std::thread)":未调用原型函数(是否是有意用变量定义的?) 35 //并且无打印输出 36 //似乎是违背了 可移动的临时对象,未默认发生移动效果 37 Scoped_thread sss(std::move(std::thread(func2))); 38 39 return a.exec(); 40 }
话题1执行输出:
std::get<C++11多线程库~线程管理>(09):运行时决定线程数量
原创文章, 转载请注明出处!