move 示例
std::ifstream是movable but not copyable,同理thread也是这样的对象.
void some_function();
void some_other_function();
std::thread t1(some_function);
std::thread t2=std::move(t1);
t1=std::thread(some_other_function); // The left item is a temporary object, and moving from temporaries is automatic and implicit
std::thread t3;
t3=std::move(t2);
t1=std::move(t3); //<--6 This assignment will terminate program!
(一个线程对象必须在退出函数的时候显示的调用detach或者join。否则会诱发std:terminate调用)
函数返回值可以是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;
}
函数参数可以是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)); // move 的使用案例
}
RAII example
class scoped_thread
{
std::thread t;
public:
explicit scoped_thread(std::thread t_):
t(std::move(t_))
{
if(!t.joinable())
throw std::logic_error(“No thread”);
}
~scoped_thread()
{
t.join();
// 慎用,如果这样不小心这样写类。则可能造成进程同步,实际没有多线程的并发优势。
}
scoped_thread(scoped_thread const&)=delete;
scoped_thread& operator=(scoped_thread const&)=delete;
};
struct func;
void f()
{
int some_local_state;
scoped_thread t(std::thread(func(some_local_state)));
do_something_in_current_thread();
}
vector储存thread对象群.
vector可以传递thread对象。采用move的方式
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)); //<--Spawn threads
}
std::for_each(threads.begin(),threads.end(),
std::mem_fn(&std::thread::join)); //<--Call join() on each thread in turn
//(std:mem_fn可以生成一个函数对象.这个函数对象供for_each调用)
}
void do_work(unsigned id);
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();
}
a joining thread class
boost库中有一个类似于下面的class,用来自动join线程.
class joining_thread
{
std::thread t;
public:
joining_thread() noexcept=default;
template<typename Callable,typename ... Args>
explicit joining_thread(Callable&& func,Args&& ... args):
t(std::forward<Callable>(func),std::forward<Args>(args)...)
{}
explicit joining_thread(std::thread t_) noexcept:
t(std::move(t_))
{}
joining_thread(joining_thread&& other) noexcept:
t(std::move(other.t))
{}
joining_thread& operator=(joining_thread&& other) noexcept
{
if(joinable())
join();
t=std::move(other.t);
return *this;
}
joining_thread& operator=(std::thread other) noexcept
{
if(joinable())
join();
t=std::move(other);
return *this;
}
~joining_thread() noexcept
{
if(joinable())
join();
}
void swap(joining_thread& other) noexcept
{
t.swap(other.t);
}
std::thread::id get_id() const noexcept{
return t.get_id();
}
bool joinable() const noexcept
{
return t.joinable();
}
void join()
{
t.join();
}
void detach()
{
t.detach();
}
std::thread& as_thread() noexcept
{
return t;
}
const std::thread& as_thread() const noexcept
{
return t;
}
};