一 主线程:
int main()
{
//程序运行起来,生成一个进程,该进程所属的主线程开始自动运行
cout << " I love China" << endl;//实际上这是主线程在执行,主线程从main()函数返回,则整个进程执行完毕。
return 0;
}
二 、子线程创建
thread
#include
#include
#include
#include
#include
#include
using namespace std;
//自己创建的线程,而需要从一个函数开始运行(初始函数)
void myprint()
{
cout << " 我的线程开始了" << endl;
cout << " 我的线程执行完毕" << endl;
}
int main()
{
//程序运行起来,生成一个进程,该进程所属的主线程开始自动运行
//cout << " I love China" << endl;//实际上这是主线程在执行,主线程从main()函数返回,则整个进程执行完毕。
return 0;
}
void myprint()
{
cout << " 我的线程开始了" << endl;
cout << " 我的线程执行完毕" << endl;
}
int main()
{
thread myobj(myprint);//thread是一个类,创建一个类对象myobj
myobj.join();
cout << " I love China" << endl;
return 0;
}
此时的结果:
从结果来看,似乎是先运行的子线程,再运行的主线程
必须明确的是:有两个线程在跑,相当于整个程序中有两条线在同时走,即使一条被阻塞,另一条也能运行。
对于thread myobj(myprint);
,这条语句包括以下要点:
对于myobj.join();
,这条语句包括以下要点:
如果不加join这句话,程序就会报错,打印结果是混乱的。
三、detach()
一般情况下:如果想保持子线程(自己用代码创建的线程)的运行状态的话,就要让主线程一直保持运行,不要让主线程运行完毕。
当我们创建了很多子线程,让主线程等待子线程们逐个结束,这种编程方法并不好,
所以出现了detach,进行线程分离,即主线程不和子线程汇合,各走各的;
//自己创建的线程,而需要从一个函数开始运行(初始函数)
void myprint()
{
cout << " 我的线程开始了" << endl;
cout << " 我的线程执行完毕1" << endl;
cout << " 我的线程执行完毕2" << endl;
cout << " 我的线程执行完毕3" << endl;
cout << " 我的线程执行完毕4" << endl;
cout << " 我的线程执行完毕5" << endl;
cout << " 我的线程执行完毕6" << endl;
cout << " 我的线程执行完毕7" << endl;
cout << " 我的线程执行完毕8" << endl;
cout << " 我的线程执行完毕9" << endl;
cout << " 我的线程执行完毕10" << endl;
}
int main()
{
thread myobj(myprint);
//myobj.join();
myobj.detach();
cout << " I love China1" << endl;
cout << " I love China2" << endl;
cout << " I love China3" << endl;
cout << " I love China4" << endl;
cout << " I love China5" << endl;
cout << " I love China6" << endl;
cout << " I love China7" << endl;
cout << " I love China8" << endl;
cout << " I love China9" << endl;
cout << " I love China10" << endl;
return 0;
}
从结果来看,主线程和子线程各走各的,子线程驻留在后台运行,当主线程结束后,子线程的结果在这里无法被打印出来。
四、joinable()
joinable():判断是否可以成功使用join()或detach();
返回true(可以join()或detach())
或false(达咩)
thread myobj(myprint);
if (myobj.joinable())
{
cout << "true!" << endl;
}
else
{
cout << "false!" << endl;
}
myobj.detach();
if (myobj.joinable())
{
cout << "true-1!" << endl;
}
else
{
cout << "false-1!" << endl;
}
class TA
{
public:
void operator()()//重载(),不带参数
{
cout << " 我的线程operator()开始了" << endl;
cout << " 我的线程operator()执行完毕" << endl;
}
};
int main()
{
TA ta;
thread myobj(ta);//ta:可调用对象
myobj.join();
cout << " I love China1" << endl;
return 0;
}
如果要用detach线程分离的话:
class TA
{
public:
int& m_i;
TA(int& i) :m_i (i){}//构造函数
void operator()()//重载(),不带参数
{
/*cout << " 我的线程operator()开始了" << endl;
cout << " 我的线程operator()执行完毕" << endl;*/
cout << "1m_i的值为:" << m_i << endl;
cout << "2m_i的值为:" << m_i << endl;
cout << "3m_i的值为:" << m_i << endl;
cout << "4m_i的值为:" << m_i << endl;
cout << "5m_i的值为:" << m_i << endl;
cout << "6m_i的值为:" << m_i << endl;
}
};
int main()
{
int myi = 6;
TA ta(myi);
thread myobj(ta);//ta:可调用对象
//myobj.join();
myobj.detach();
cout << " I love China1" << endl;
return 0;
}
在此例中,使用的detach进行线程分离,子线程中使用的引用传递,当主线程执行完后,myi这个值就会被销毁,而子线程此时却不一定执行结束,此时就会发生不可预料的结果。
如果使用值传递,相当于拷贝的一份值,主线程结束也不影响子线程。
还有需要注意的是:
问:一旦调用了detach(),当主线程执行结束,这个ta对象,还在吗?
答:不在,但没关系,这个对象实际上被复制到子线程中去,执行完主线程后,复制品依然存在。
所以只要TA对象里没有引用,指针,就不会产生问题。
class TA
{
public:
int m_i;
TA(int i) :m_i (i)
{
cout << "TA()的构造函数执行" << endl;
}
TA(const TA& ta)
{
m_i = ta.m_i;
cout << "TA()的拷贝构造函数执行" << endl;
}
~TA()
{
cout << "TA()的析构函数执行" << endl;
}
void operator()()//重载(),不带参数
{
/*cout << " 我的线程operator()开始了" << endl;
cout << " 我的线程operator()执行完毕" << endl;*/
cout << "1m_i的值为:" << m_i << endl;
cout << "2m_i的值为:" << m_i << endl;
cout << "3m_i的值为:" << m_i << endl;
cout << "4m_i的值为:" << m_i << endl;
cout << "5m_i的值为:" << m_i << endl;
cout << "6m_i的值为:" << m_i << endl;
}
};
int main()
{
int myi = 6;
TA ta(myi);
thread myobj(ta);//ta:可调用对象
myobj.join();
//myobj.detach();
cout << " I love China1" << endl;
return 0;
}
从结果可以看出发生了拷贝。
第一个打印的析构为子线程的析构,第二个为主线程的析构。
2 用lambda表达式
int main()
{
//线程入口
auto mylambthread = [] {
cout << " 我的线程开始了" << endl;
cout << " 我的线程执行完毕10" << endl;
};
thread myobj(mylambthread);
myobj.join();
cout << " I love China1" << endl;
return 0;
}