如果需要等待线程结束,就在线程的实例对象上调用join()。在管理线程之创建线程最后的例子中,用my_thread.join()代替my_thread.detach()就可以确保在函数终止前、局部变量析构前,线程会终止。在这种情况下,用分开的线程来运行函数就没有什么意义了。因为在等待my_thread终止时,这个线程就不做任何事情了。在实际的工程应用中,要么这个线程做自己的事,要么创建多个线程等待它们结束。
join()是简单粗暴的,或者你等待线程终止,或者你不等待。如果想要更加精确控制,例如检查这个线程是否终止,或只是等待某一段时间,这是你必须使用其他方法例如条件变量等。线程调用join()会清理相应的内存空间,调用join()后,std::thread对象就不再和这个线程相关了。这也就是意味着,对于一个线程实例对象,你仅仅可以调用join()一次,在调用后,这个线程对象就不在是joinable,调用joinable()会返回false。
struct func;
void f()
{
int some_local_state=0;
func my_func(some_local_state);
std::thread t(my_func);
try
{
do_something_in_current_thread();
}
catch(...)
{
t.join();
throw;
}
t.join();
}上面代码使用try/catch模块来确保调用join(),无论是否发生异常。使用try/catch有点冗长(verbose),而且容易出现作用域错误,不是理想的解决方法。class thread_guard
{
std::thread& t;
public:
explicit thread_guard(std::thread& t_):t(t_){}
~thread_guard()
{
if(t.joinable())//先检查是否已经掉用过join
t.join();
}
//下面是禁止使用拷贝构造函数和赋值操作符,这需要
//C++11的支持
thread_guard(thread_guard const&)=delete;
thread_guard& operator=(thread_guard const&)=delete;
};
struct func;
void f()
{
int some_local_state=0;
func my_func(some_local_state);
std::thread t(myfunc);
thread_guard g(t);
do_something_in_current_thread();
}上面的原理是局部变量会按照构造的逆顺序销毁,因为这些变量都在栈上。thread_guard对象g首先销毁,在它的析构函数调用了join()。void edit_document(std::string const& filename)
{
open_document_and_display_gui(filename);
while(!done_editing())//编辑是否完成
{
user_command cmd=get_user_input();//用户输入命令
if(cmd.type==open_new_document)//要打开新文档
{
std::string const new_name=get_filename_from_user();
std::thread t(edit_document,new_name);//创建线程
t.detach();//分离,在后台运行
}
else
{
process_user_input(cmd);
}
}
}原文:http://blog.csdn.net/kangroger/article/details/39930431