线程 join 用法
#include <iostream>
#include <thread>
using namespace std;
void Myprintf()
{
cout << "子线程开始运行了" << endl;
// ...
cout << "子线程运行结束了" << endl;
}
int main()
{
thread subth(Myprintf); // 创建一个子线程,子线程的函数入口地址为 Myprintf
subth.join(); // 等待子线程运行结束,主线程继续向下执行, 不加这个函数,则主线程退出后,整个进程就结束了,子线程就无法顺利执行到结束
cout << "主线程运行结束了" << endl;
return 0;
}
程序运行结果如下所示:
线程 detach 用法
#include <iostream>
#include <thread>
using namespace std;
void Myprintf()
{
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 subth(Myprintf); // 创建一个子线程,子线程的函数入口地址为 Myprintf
subth.detach(); // subth 子线程与主线程分离,子线程与主线程各自执行各自的,互不影响,子线程被放入后台去执行了, 一旦使用的 detach, 后续就不能使用 join
cout << "L Love China 1" << endl;
cout << "L Love China 2" << endl;
cout << "L Love China 3" << endl;
cout << "L Love China 4" << endl;
cout << "L Love China 5" << endl;
cout << "L Love China 6" << endl;
cout << "L Love China 7" << endl;
cout << "L Love China 8" << endl;
return 0;
}
程序运行结果如下所示:
由于子线程使用了 detach,子线程就运行在后台中了,主线程在退出前,不需要在等待子线程运行结束, 由系统来回收子线程的资源;主线程退出后,子线程剩下的一些打印操作就对这个进程无效了。
joinable() : 判断某个线程是否可以 join() 或者 detach(),成功返回 true,失败返回 false。
使用类对象来创建子线程
#include <iostream>
#include <thread>
using namespace std;
class TA
{
private:
int& m_i;
public:
TA(int& i) : m_i(i)
{
cout << "TA 的构造函数被调用了" << endl;
}
TA(const TA& obj) : m_i(obj.m_i)
{
cout << "TA 的拷贝构造函数被调用了" << endl;
}
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;
}
~TA()
{
cout << "TA 的析构函数被调用了" << endl;
}
};
int main()
{
int i = 6;
TA ta(i);
thread subth(ta); // ta: 可调用对象
// subth.join();
subth.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;
return 0;
}
使用 detach 的运行结果如下所示:
由于使用了线程分离,所以主线程和子线程各自运行各自的,类中有一个对象是引用,当主线程运行结束后,主线程所使用的一些变量的内存空间就被释放了,这会使子线程 ta 中的 m_i 引用的是一段被释放的内存空间,从而可能会产生出错;所以,使用类对象来创建子线程,并且调用 detach() 时,类里面不能有指针或者引用。
主线程结束后,类对象 ta 的内存空间也被释放了,然而子线程也依然可以安全的调用,这是因为使用类对象来创建子线程时,会将这个类对象拷贝一份到子线程中。
析构函数的调用者为 ta。
使用 join的运行结果如下所示:
主线程等待子线程运行结束后继续向下执行,所以就不需要考虑这个类是否含有引用或者指针这个问题。
第一个析构函数的调用者为 ta 的复制品,第二个析构函数的调用者为 ta。
使用 lambda 表达式创建线程
#include <iostream>
#include <thread>
using namespace std;
int main()
{
auto lamth = []()
{
cout << "子线程开始运行" << endl;
cout << "子线程结束运行" << endl;
};
thread subth(lamth);
subth.join();
cout << "I Love China" << endl;
return 0;
}
程序运行结果如下所示: