多线程的创建
在C++11 中 多线程的创建
1. 引入头文件
#include <thread>
2. join()、detach()以及jionable()
- join()主要是指当创建子线程后,子线程执行,主线程要在某个地方等待子线程执行完毕。
- detach() 创建子线程后,子线程与主线程分离称为守护线程,它的资源之内的东西,由系统管理。
使用detach()时,要避免使用主线程中的引用,指针之内的东西。否则当主线程释放相应资源时,子线程可能出现未知的bug。
*** join() 与detach()*** 不能同时使用。
- joinable() 主要用于判断当前位置是否能够使用join() 或者 detach(), 返回值为true或者false
3. 创建子线程的方式
1. 函数方式
#include "pch.h"
#include <iostream>
#include <thread>
using namespace std;
void myprintf() {
cout << "this is my first created thread " << endl;
cout << "the created thread end" << endl;
}
int main()
{
thread myojbk(myprintf);
myojbk.join();
//myojbk.detach();
cout << "Hello World!\n<<endl;";
return 0;
}
2. 类的方式
#define LEN_INT int
class Test {
private:
LEN_INT value;
public:
bool operator () ();
Test(LEN_INT);
virtual~Test();
Test(const Test& t);
};
int main()
{
LEN_INT data = 3;
Test te(data);
thread classThread(te);
if (classThread.joinable()) {
classThread.join();
}
return 0;
}
注意在使用detach() 时不要在类中使用与主线程相关的引用和指针
当主线程结束时相应的资源被释放,而守护线程是引用主线程的资源,这样可能会出现未知的bug.
问题2. 当使用detach()时,传的类会有影响吗?
不会的,类在使用线程时,会调用复制构造函数
2. lambda
auto lamdaThread = []{
std::cout << "my lamda thread create" << std::endl;
std::cout << "my lamda thread recall" << std::endl;
};
thread mythread3(lamdaThread);
mythread3.join();
使用lambda函数创建线程还可以避免这样一种情况。
class A{
public:
void operator()(){
// do something
}
};
int main() {
std::thread my_thread(A());
}
注意这里的情况std::thread my_thread(A());
,这里会把这A()是一个右值,这里可能把这个当成一个函数定义,函数名是my_thread 参数是一个A对象,返回是一个std::thread
避免这种情况可以再加一对括号std::thread my_thread((A()));
或者写成lambda函数。
3.类对象内部使用某个子成员函数创建线程
这种情况通常会加上this参数
class A{
public:
void do_something(int i){}
void do_other_thing{
int i = 0;
std::thread my_thread(do_something,this, i);
}
};
类外使用记得创建对象,或将使用的函数申明成static
int main(){
A a;
std::thread my_thread(do_something, &a, param);
}