``
C++11创建线程的方法
一、普通函数创建线程
#include <iostream>
#include <thread>
void print(const int& a,const char *str)
{
std::cout << "主线程传递的参数a = " << a << std::endl;
std::cout << "参数a的地址为" << &a << std::endl;
std::cout << "主线程传递的参数str = " << str << std::endl;
std::cout << "参数str的地址为" << (void*)str << std::endl;
return;
}
int main()
{
int var = 3;
const char str[] = "hello world!";
std::thread mythread(print, var,str);
mythread.join();
std::cout << "主线程中var的地址为" << &var << std::endl;
std::cout << "主线程中str的地址为" << &str << std::endl;
return 0;
}
通过观察输出结果我们可以发现,通过thread创建线程成功,但是存在问题,print的第一个参数a为引用传递,但是主线程和子线程对于参数a的地址不同,说明在子线程中的参数a是复制var的数值,本质是数值传递,需要解决这个问题,需要使用std::ref函数来解决。
通过使用std::ref函数可以真正的实现引用传递,但是如果我们把join换的detach,在主线程执行完毕时,str的地址被释放,如果子线程还未执行完毕,则会发生异常。
二、使用类对象创建线程
#include <iostream>
#include <thread>
class A
{
public:
A()
{
std::cout << "构造函数执行" << std::endl;
std::cout << "执行的线程ID为" << std::this_thread::get_id() << std::endl << std::endl;
}
A(const A& temp)
{
std::cout << "拷贝构造函数执行" << std::endl;
std::cout << "执行的线程ID为" << std::this_thread::get_id() << std::endl << std::endl;
}
~A()
{
std::cout << "析构函数执行" << std::endl;
std::cout << "执行的线程ID为" << std::this_thread::get_id() << std::endl << std::endl;
}
void operator()()
{
std::cout << "子线程执行" << std::endl;
std::cout << "子线程线程ID为" << std::this_thread::get_id() << std::endl << std::endl;
}
};
int main()
{
A a;
std::cout << "主线程ID为" << std::this_thread::get_id() << std::endl << std::endl;
std::thread mythread(a);
mythread.join();
return 0;
}
通过观察输出结果,在利用类对象创建线程的时候,需要对()进行运算符重载,子线程执行()运算符重载的代码,但是执行了一次拷贝构造函数,显得有些多余,浪费性能,使用std::ref可以解决这个问题。
这样就少执行了一次拷贝构造函数以及析构函数。
三、Lambda表达式创建线程
#include <iostream>
#include <thread>
#include <chrono>
int main()
{
auto myLambda = [] {
std::cout << "子线程1开始执行" << std::endl;
};
std::thread mythread1(myLambda);
std::thread mythread2([]{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "子线程2开始执行" << std::endl;
});
mythread1.join();
mythread2.join();
return 0;
}
四、类的成员函数创建线程
#include <iostream>
#include <thread>
class A
{
public:
void demo(int& a)
{
std::cout << "线程开始执行" << std::endl;
std::cout << "子线程ID为" << std::this_thread::get_id() << std::endl << std::endl;
}
};
int main()
{
A a;
int var = 4;
std::thread mythread(&A::demo,std::ref(a),std::ref(var));
mythread.join();
return 0;
}