一、使用函数对线程的创建、启动、结束
(1)包含头文件
#include <thread>
(2) 写初始函数(根据需求自己定义)
void MyPrintf()
{
cout<<"我创建的线程开始执行了"<<endl;
...
cout<<"我创建的线程执行结束了"<<endl;
}
(3)定义对象
3.1 thread是标准库中的一个类
3.2 join()加入汇合,阻塞主线程执行
3.3 良好的书写规范:主线程必须等待子线程执行完毕后,才能关闭退出
int mian()
{
// thread是标准库中的一个类 ,MyPrintf是实参,是可调用对象
//(1)创建了线程,线程执行起点(入口)MyPrintf (2)开始执行线程MyPrintf方法
thread myObj(MyPrintf);
//join()作用:主线程阻塞到这里,等待子线程MyPrintf执行完,当子线程执行完毕,和主线程会合,然后继续向下继续执行
myObj.join()
return 0;
}
(4)detach()
4.1 作用:分离主线程和子线程的依赖关系,主线程不用等待子线程汇合,也可以退出;
4.2 一旦detach后,与主线程关联的thread对象就会失去关联,子线程就会驻留在后台继续执行,由后台运行时库进行线程资源的清理工作;
4.3 使用detach(),就不能再用join();
int mian()
{
thread myObj(MyPrintf);
myObj.detach();
return 0;
}
(5)joinable()
作用:判断是否可以使用join()或者detach(),返回值是bool类型
int mian()
{
thread myObj(MyPrintf);
if(myObj.joinable())
{
//可以执行join汇合,具体实现根据需求自己定义
myObj.join()
...
}
else
{
//可以执行detach分离
myObj.detach()
...
}
return 0;
}
二、其他创建线程的方法
(1)使用类:
class TA
{
public:
void operator()() //不带参数
{
cout<<"我的线程执行开始了"<<endl;
......
cout<<"我的线程执行结束了"<<endl;
}
};
int mian()
{
TA a;
thread mythread(a); //通过类对象调用,执行线程
a.join();
return 0;
}
class TA
{
public:
int &m_i; //成员变量为引用时,不能用detach(),如果是int整形普通变量则可以,考虑引用内存回收的问题
TA(int &i):m_i(i)
{}
void operator()() //带参数
{
cout << "我的线程执行开始了" << endl;
cout << "m_i的值为:"<< m_i << endl;
cout << "我的线程执行结束了" << endl;
}
};
int mian()
{
int num = 9;
TA ta(num);
thread mythread(ta); //通过类对象调用,执行线程
ta.join();
//注意:成员变量不是引用或者指针,一旦调用了detach(),主线程执行完毕后,ta会被销毁,ta对象就不存在了;但是对象ta会被复制一份到线程中依旧存在,继续执行;
// ta.detach();
return 0;
}
class TA
{
public:
int m_i; //成员变量为引用时,不能用detach(),如果是int整形普通变量则可以,考虑引用内存回收的问题
TA(int i):m_i(i)
{
cout << "构造函数被执行" << endl;
}
TA(const TA &ta):m_i(ta.m_i)
{
cout << "拷贝构造函数被执行" << endl;
}
~TA()
{
cout<<"析构函数被执行"<<endl;
}
void operator()() //带参数
{
cout << "我的线程执行开始了" << endl;
cout << "m_i的值为:"<< m_i << endl;
cout << "我的线程执行结束了" << endl;
}
};
int mian()
{
int num = 9;
TA ta(num);
thread mythread(ta); //通过类对象调用,执行线程
//注意:成员变量不是引用或者指针,一旦调用了detach(),主线程执行完毕后,ta会被销毁,ta对象就不存在了;但是对象ta会被复制一份到线程中依旧存在,继续执行;
mythread.detach();
//析构函数会被执行两次,第一次是主线程结束的析构,第二次是复制后的析构;
return 0;
}
(2)使用Lambda表达式
int mian()
{
auto myLamthread[]
{
cout << "我的线程执行开始了" << endl;
....
cout << "我的线程执行结束了" << endl;
}
thread mythread(myLamthread); //通过lambda表达式调用,执行线程
mythread.join();
return 0;
}