两种情况:
- 写一个用来在后台启动线程的函数,现在想通过新线程返回的所有权去调用这个函数,而不是等待这个等待线程结束再去调用。
- 创建一个线程,并想要在函数中转移所有权必须等待线程结束。
上面中情况都涉及到新线程的所有权转移,这是移动引入std::thread的原因。在C++标准库中有很多资源占有( resource-owning) 类型, 比如 std::ifstream , std::unique_ptr 还有 std::thread , 都是可移动( movable) , 且不可拷贝( cpoyable) 的。
void some_function();
void some_other_function();
std::thread t1(some_function); // 1
std::thread t2=std::move(t1); // 2
t1=std::thread(some_other_function); // 3
std::thread t3; // 4
t3=std::move(t2); // 5
t1=std::move(t3);// 6 赋值操作将使程序崩溃
不能通过赋一个新值给std::thread对象方式来丢弃一个线程。
std::thread支持移动,就意味着线程的所有权,可以在函数外进行转移
std::thread f()
{
void some_function();
return std::thread(some_function);
}
std::thread g()
{
void some_other_function(int);
std::thread t(some_other_function,42);
return t;
}
同样的,当所有权可以在函数内部传递,这就允许将std::thread实例当做参数进行传递:
void f(std::thread t);
void g()
{
void some_function();
f(std::thread(some_function));
std::thread t(some_function);
f(std::move(t));
}
线程所做的工作都是独立的,并且结果仅受到共享数据的影响。
void do_work(unsigned id);
void f()
{
std::vector<std::thread> threads;
for(unsigned i=0; i < 20; ++i)
{
threads.push_back(std::thread(do_work,i)); // 产生线程
}
std::for_each(threads.begin(),threads.end(),
std::mem_fn(&std::thread::join)); // 对每个线程调用join()
}