线程归属权转移,在C++中,线程只可移动不可拷贝,有明确归属权。
线程只可move不可copy,对于线程,需要使用std::move(线程)进行转移。
#include
#include
void some_function()
{
std::cout << 1 << std::endl;
}
void some_other_function()
{
std::cout << 2 << std::endl;
}
auto main(int /*unused*/, char * /*argv*/[]) -> int
{
//创建线程
std::thread t1(some_function);
//通过移动语义转移线程
std::thread t2 = std::move(t1);
//转移后的线程重新开启
t1 = std::thread(some_other_function);
std::thread t3;
//通过move语义转移线程
t3 = std::move(t2);
//合并线程
t1.join();
//合并线程后移动线程
t1 = std::move(t3);
t1.join();
return 0;
}
我们可以向默认初始化的线程 t3 转移线程,可以向合并后的线程 t1 转移线程,也可以在线程初始化时 (t2) 转移线程,但不可以在已经持有资源的线程( 未被join或转移前的 t1 )转移线程,否则会导致程序崩溃。
std::thread t1(some_function);
std::thread t3(some_other_function);
//崩溃
t1 = std::move(t3);
由于函数返回结果是临时变量,所以可以用于转移线程
std::thread f()
{
//声明函数
void some_fuction();
//返回线程
return std::thread(some_fuction);
}
void some_fuction()
{
std::cout << 1 << std::endl;
}
对于C++,RAII 的思想也可以用于线程,保证 thread 变量生命周期结束前,线程必然完结。
#include
#include
struct scopedThread
{
explicit scopedThread(std::thread t_)
: t(std::move(t_))
{
if (!t.joinable())
{
throw std::logic_error("No thread");
}
}
~scopedThread()
{
t.join();
}
scopedThread(const scopedThread &) = delete;
auto operator=(const scopedThread &) -> scopedThread & = delete;
private:
std::thread t;
};
struct func
{
explicit func(int &i_)
: i(i_)
{}
void operator()() const
{
for (unsigned j = 0; j != 3; ++j)
{
fprintf(stdout, "%d%s\n", i, "test");
}
}
private:
int i;
};
void f()
{
int some_local_state;
scopedThread t{std::thread(func(some_local_state))};
for (int i = 0; i != 100; ++i)
{
std::cout << "_";
}
}
auto main(int /*unused*/, char * /*argv*/[]) -> int
{
f();
return 0;
}
支持移动语义的容器可以装载thread变量,根据需要创建线程。需要提醒的是,这并不一定比单线程效率高。
void do_work(unsigned id)
{
std::cout << id << std::endl;
}
void f()
{
std::vector<std::thread> threads;
for (unsigned i = 0; i != 20; ++i)
{
threads.emplace_back(do_work, i);
}
for (auto &entry : threads)
{
entry.join();
}
}
auto main(int /*unused*/, char * /*argv*/[]) -> int
{
joining_thread test(print);
f();
return 0;
}
线程只支持移动,不支持拷贝,这是很容易理解的,也就是所谓的所有权转移,读者可简单练习体会。