1 #include <QCoreApplication> 2 #include <thread> 3 #include <iostream> 4 5 /* 6 * 话题1:转移线程的所有权。 7 * std::thread 构造函数需传入一个函数或可调用对象, 每一个 std::thread 都关联着一个函数或可调用对象。 8 * 两者之间的关联性,在不同 std::thread 对象之间是可以发生转移的。 9 * 比如:函数 fun()本来与 std::thread A 关联着,我们可以通过转移线程的所有权, 10 * 将 func() 与 std::thread B 关联。所有权的转移,即便是 线程A 中 func()还未执行结束,也可以发生所有权转移。 11 * 线程的所有权之所以能够转移,得益于 std::thread 对移动的支持。C++标准库中有很多资源占有类型(resource-owning), 12 * 比如:std::ifstream, std::unique_ptr, std::thread都是可移动不可拷贝的。 13 * 14 * 15 * 小条儿1:临时对象作为返回值,或者临时对象拿去赋值给别的对象, 这两种情况下, 如果临时对象可移动, 移动操作将会隐式的发生。 16 * 小条儿2:命名对象作为返回值,如果命名对象可移动,则移动操作会隐式的发生; 命名对象拿去赋值给别的对象,通过 std::move 可显示的发生移动操作。 17 * 小条儿3:std::terminate() 是 noexcept函数,终止程序且不会抛出异常。重点关注不会抛出异常。 18 */ 19 20 void hello(){ 21 for (int i = 10; i>0; --i) 22 std::cout<<"hello word "<<i<<std::endl; 23 } 24 25 int main(int argc, char *argv[]) 26 { 27 QCoreApplication a(argc, argv); 28 29 std::thread t1(hello); //t1 与 hello() 关联 30 std::thread t2(std::move(t1)); //t1所属的线程所有权转移给了t2 31 if (t1.joinable()){ 32 std::cout<<"t1.joinable()"<<std::endl; 33 } 34 if (t2.joinable()){ 35 std::cout<<"t2.joinable()"<<std::endl; 36 } 37 38 39 std::thread t11(hello); 40 //t2 = std::move(t11); //运行崩溃:t2拥有一个线程的所有权,并且还未执行结束。 41 //一个 std::thread 同一时间只能拥有一个线程资源。 42 //再次把其他 std::thread 所有权转移给 t2之前,可以 43 //先执行 t2.join(), 等待 t2 的线程执行结束后,再接收别的所有权。 44 45 t2.join(); 46 t11.join(); 47 return a.exec(); 48 }