创建线程的几种方法
- 使用函数作为thread对象的可调用对象
#include
#include
using namespace std;
void myprint() //创建自己的线程,初始函数
{
cout << "my thread begin ..." << endl;
cout << "my thread running1 ..." << endl;
cout << "my thread running2 ..." << endl;
cout << "my thread running3 ..." << endl;
cout << "my thread running4 ..." << endl;
cout << "my thread running5 ..." << endl;
cout << "my thread running6 ..." << endl;
cout << "my thread running7 ..." << endl;
cout << "my thread running8 ..." << endl;
cout << "my thread running9 ..." << endl;
cout << "my thread running10 ..." << endl;
cout << "my thread end....." << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
/*
* 线程运行的开始和结束
* 程序运动起来,生成一个进程,该进程的主线程自动运行起来;
* cout << “I love C++” << endl; 实际上是主线程在运行,主线程从main()函数返回,则整个进程结束;
* 主线程从main()函数开始执行,则我们自己创建的线程也需要从一个函数开始运行(初始函数),一旦这个函数结束,子线程结束;
* 整个进程是否执行完毕的标志是主线程是否执行结束,
* 一般情况下下:如果想要子线程处于执行状态的话,则需要保持主线程运行;
*/
/*
(1) thread:标准库中的类
(2) join(); 加入/汇合,阻塞主线程,等待子线程执行完毕,然后子线程和主线汇合
(3) detach(): 分离,主线程、子线程各自执行,主线程不必要等子线程执行完毕; 不建议!!!
(4) joinable(): 判断是否可以成功使用join()或者detach()
*/
thread myobj(myprint); //myprint是可调用对象;
//(1)创建了一个线程,线程执行入口(初始函数):myprint; (2)myprint线程开始执行;
//myobj.join();
//(3)join():加入/汇合,阻塞主线程,等待子线程执行完毕,然后子线程和主线汇合
if (myobj.joinable() == true) //一般使用detach()后就不能使用join(),否则会报错
{
cout << "1:join() == true" << endl;
}
else
{
cout << "1:join() == false" << endl;
}
myobj.detach();
if (myobj.joinable() == true) //一般使用join()后就不能使用detach(),否则会报错
{
cout << "2:detach() == true" << endl;
}
else
{
cout << "2:detach() == false" << endl;
}
//(4) detach():一般detach后,那么与主线程关联的thread对象失去与这个主线程的关联,此时子线程会驻留在后台运行,这个子线程被C++运动时刻接管,由运行时刻库负责清理该线程相关的资源(守护线程)
cout << "Main thread runing1...." << endl;
cout << "Main thread runing2...." << endl;
cout << "Main thread runing3...." << endl;
cout << "Main thread runing4...." << endl;
cout << "Main thread runing5...." << endl;
cout << "Main thread end...." << endl;
return 0;
}
-
使用类对象(可调用函数)
class YHB
{
public:
int &m_i; //解决bug方法,去除引用
YHB(int &i) : m_i(i) //解决bug方法,去除引用
{
cout << “YHB()构造函数被执行” << endl;
}
YHB(const YHB &yhb) : m_i(yhb.m_i)
{
cout << “YHB()拷贝构造函数被执行” << endl;
}
~YHB()
{
cout << “YHB()析构函数被执行” << endl;
}void operator()() //不能带参数
{
//cout << “my thread: opeartor() begin …” << endl;
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 << “my thread: opeartor() end …” << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
YHB yhb;
thread myobj(yhb);
myobj.join();
cout << “Main thread end…” << endl;
return 0;
错误使用
int myi = 5;
YHB yhb(myi); //执行构造函数
thread myobj(yhb); //执行拷贝构造函数
myobj.detach();
//此时使用detach()将有可能产生bug,因为变量i是主线程中的临时变量,有可能主线程结束了,但是子线程仍在运行,但是需要y引用i的值,但此时主线程已经结束,变量i已经销毁
//那对象yhb呢? 这个对象其实是复制到线程中去的,如果主线程中的yhb对象销毁,则子线程中复制的yhb对象依然会存在;
//所以,主要这个类对象中没有引用 指针就没有问题
//解决bug方法,去除YHB类中的引用即可
}
- 使用lambda表达式
auto mylanthread = []
{
cout << “my lambda thread begin…” << endl;
//…
cout << “my lambda thread end…” << endl;
};
thread myobj(mylanthread);
myobj.join();
cout << “Main thread end…” << endl;