前面的内容知道,程序运行起来,生成一个进程,该进程所属的主线程从main方法开始自动运行直到return 结束。
我们创建一个线程,也要从一个函数开始运行,一旦这个函数运行起来,就代表着我们这个线程开始运行,一旦这个函数运行结束,就代表着这个线程运行结束。
C++11提供了thread 这个类,因此第一步就是要 #include
使用 thread 类 ,构建对象的时候,传递的参数是一个方法,我们这里 是:mythreadmethod().
暂时没有传递参数。
我们知道,当主线程执行完毕后,进程也就挂了。如果主线程都执行完毕了,子线程还没有执行完毕,那么一般情况下,进程就会有runtime exception。
因此,在一般情况下,我们要让主线程等待子进程结束。因而引出了join()方法的使用
// 002createthread_join_detach.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include
#include
using namespace std;
void mythreadmethod() {
cout << "mythreadmethod start..." << endl;
cout << "mythreadmethod end..." << endl;
}
int main()
{
std::cout << "Hello World start!\n";
thread mythread(mythreadmethod);//这句话的意思是:1.创建一个子线程;2.该线程执行起点是mythreadmethod方法;3.mythreadmethod方法就已经抢占CPU开始执行,但是并不一定能抢过其他线程。
mythread.join();//join方法的意思是:作用是阻塞主线程,让主线程等待子线程执行完毕,然后子线程和主线程汇合,然后再沿着主线程没有完成代码往下走。
std::cout << "Hello World end!\n";
}
作用是阻塞主线程,让主线程等待子线程执行完毕,然后子线程和主线程汇合,然后再沿着主线程没有完成代码往下走。
原因也很简单,当主线程先于子线程执行完成的case发生的时候:
主线程结束 = 进程结束
但是这时候子线程没有结束,那么这时候子线程依附于谁存在呢?换句话说:子线程中的临时变量,方法等,谁来回收呢?因此就有runtime exception
从上面知道,传统多线程程序:主线程使用join()方法等到子线程执行完毕,然后再执行自己的逻辑。
那么能不能主线程自己结束就结束,不用管子线程呢?
detach()方法就是干这个的。
当主线程结束的时候,主线程中的值能否使用?
如果线程对象传递的方法中有参数,且这个参数是从主线程传递过去的,当主线程运行结束后,那么这个参数能否使用?
该函数的作用是判断,join()或者 detach()方法能否使用?
运用时机:当程序很大的,最好判断一下。
结论:
当使用了join方法后,就不能再次使用join 和 detach方法了
当使用了detach方法后,就不能再次使用join 和 detach方法了
会runtime exception,原因未知。
class AA {
public:
void operator()() {
cout << "class AA operator()() start..." << endl;
cout << "class AA operator()() end..." << endl;
}
int age;
};
//运行结果为:
//Hello World0 start!
//class AA operator()() start...Hello World1 end!
// Hello World2 end!
// Hello World3 end!
// Hello World4 end!
//
// class AA operator()() end...
// Hello World5 end!
// Hello World6 end!
void main() {
AA aa;
std::cout << "Hello World0 start!\n";
thread mythread(aa);
std::cout << "Hello World1 end!\n";
std::cout << "Hello World2 end!\n";
std::cout << "Hello World3 end!\n";
std::cout << "Hello World4 end!\n";
mythread.join();
std::cout << "Hello World5 end!\n";
std::cout << "Hello World6 end!\n";
}
//创建线程的方法,使用operator()函数做为 线程的入口函数
class Teacher141 {
public:
void operator()() {
for (int i = 0; i < 10;i++) {
cout << "Teacher141 的 operator() 没有参数的方法被调用" << endl;
}
}
void operator()(int num ) {
for (int i = 0; i < 10;i++) {
cout << "Teacher141 的 operator(int num) 的方法被调用: num = " << num << endl;
}
}
void Teacher141func(int num) {
m_age = num;
cout << "Teacher141 的 operator() 没有参数的方法被调用" << endl;
}
int m_age;
};
//operator()()做thread 启动方法入口
void main() {
cout << " test thread start " << endl;
//operator()()做thread 启动参数
Teacher141 t1;
thread mythread1(t1);
//operator()(T t)做thread 启动参数
Teacher141 t2;
thread mythread12(t2,20);
mythread1.join();
mythread12.join();
//test thread start
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用Teacher141 的 operator(int num) 的方法被调用: num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator(int num) 的方法被调用 : num = 20
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用
// Teacher141 的 operator() 没有参数的方法被调用
// test thread end
cout << " test thread end " << endl;
}
//类的成员函数做 线程启动函数入口
class Teacher142 {
public:
void writeTeacherName() {
for (int i = 0; i < 1000; i++) {
cout << " 子线程id 为 : " << this_thread::get_id() << " i = " << i << endl;
}
}
};
void main() {
Teacher142 tea;
int a = 10;
thread mythread(&Teacher142::writeTeacherName,&tea);
for (int i = 0; i < 1000;i++) {
cout << "主线程id 为 : " << this_thread::get_id() << " i = " << i << endl;
}
mythread.join();
}
[](){}
//运行结果为:
//Hello World0 start!
//mylambdathread start...Hello World1 end!
//Hello World2 end!
//Hello World3 end!
//Hello World4 end!
//
//mylambdathread end...
//Hello World5 end!
//Hello World6 end!
void main() {
std::cout << "Hello World0 start!\n";
auto mylambdathread = []() {
cout << "mylambdathread start..." << endl;
cout << "mylambdathread end..." << endl;
};
thread mythread(mylambdathread);
std::cout << "Hello World1 end!\n";
std::cout << "Hello World2 end!\n";
std::cout << "Hello World3 end!\n";
std::cout << "Hello World4 end!\n";
mythread.join();
std::cout << "Hello World5 end!\n";
std::cout << "Hello World6 end!\n";
}