1.线程分离–detach()
主线程不必等子线程运行完毕,先走为敬!
struct func
{
int& i;
func(int& i_) : i(i_) {}
void operator() ()
{
for (unsigned j=0 ; j<1000000 ; ++j)
{
do_something(i); // 1. 潜在访问隐患:悬空引用
}
}
};
void oops()
{
int some_local_state=0;
func my_func(some_local_state);
std::thread my_thread(my_func);
my_thread.detach(); // 2. 不等待线程结束
}
主函数线程已结束,my_thread线程中的函数还在运行.
2.等待线程完成–join()
- 将my_thread.detach()替换为my_thread.join(),就可以确保局部变量在线程完成后,才被销毁.
- 调用join()的行为,还清理了线程相关的存储部分,这样std::thread对象将不再与已经完成的线程有任何关联。这意味着,只能对一个线程使用一次join();一旦已经使用过join(),std::thread对象就不能再次加入了,当对其使用joinable()时,将返回false。
3.判断是否可以成功使用join()或者detach()的-joinable()
#include <iostream>
#include <thread>
using namespace std;
void myprint()
{
cout<< "我的线程开始执行了"<<endl;
cout<< "我的线程运行结束了"<<endl;
}
int main (void)
{
thread mytob(myprint);
if (mytob.joinable())
{
cout<<"true"<<endl;
}
else
{
cout<<"false"<<endl;
}
mytob.join();
if (mytob.joinable())
{
cout<<"true"<<endl;
}
else
{
cout<<"false"<<endl;
}
cout<<"i love china "<<endl;
return 0;
}
运行结果
true
我的线程开始执行了
我的线程运行结束了
false
i love china
所以可以改进成这样的形式:
#include <iostream>
#include <thread>
using namespace std;
void myprint()
{
cout<< "我的线程开始执行了"<<endl;
cout<< "我的线程运行结束了"<<endl;
}
int main (void)
{
thread mytob(myprint);
if (mytob.joinable())
{
mytob.join();
}
return 0;
}
4.异常问题应避免的
#include <iostream>
#include <thread>
using namespace std;
class TA{
public:
int &m_i;
TA(int &i):m_i(i) {}
void operator()()
{
cout<<"m_i1的值为"<<m_i<<endl;
cout<<"m_i2的值为"<<m_i<<endl;
cout<<"m_i3的值为"<<m_i<<endl;
cout<<"m_i4的值为"<<m_i<<endl;
cout<<"m_i5的值为"<<m_i<<endl;
cout<<"m_i6的值为"<<m_i<<endl;
}
};
int main (void)
{
int mi=6;
TA ta(mi);
thread mytob(ta);
mytob.detach();
cout<<" i love china "<<endl;
return 0;
}
运行结果为:
i love china
m
原因这是因为主线程运行完之后,引用的变量就已经被销毁了.但这个变量还在子线程中在用,所以导致程序异常,产生不可预料的结果.
另一个知识点是:一旦调用了detach(),那主线程执行结束了,这里用到的ta对象还存在吗?答案是不存在的
但这个对象是被复制到子线程中去,原来的ta会被销毁,但是所复制的TA对象依旧存在.所以只要这个TA类对象里没有引用,没有指针,那么就不会产生问题.
5.用lambda表示
#include <iostream>
#include <thread>
using namespace std;
int main (void)
{
auto mylamthread =[]{
cout<<"我的线程开始了"<<endl;
cout <<"我的线程结束了"<<endl;
};
thread mytob(mylamthread);
mytob.join();
cout<<"i love china "<<endl;
return 0;
}
运行结果为:
我的线程开始了
我的线程结束了
i love china