创建线程

  • include
  • thread thread1(func_name,args);
    • 第一个参数代表一个函数名称
    • 第二个参数代表该函数的参数
  • 声明一个thread变量,当前线程就会开始执行传入的函数

结束线程

  • thread1.join();
  • 当一个线程启动的时候主程序不会等待线程结束才会继续往下执行,所以有可能会导致线程还没有执行完,主程序就结束了,所以加上一个join函数的调用,主程序在结束之前会检测线程是不是已经结束。

分离线程

  • thread1.detach();
  • 调用这个函数之后主程序不需要等待线程结束之后再结束,主程序可以先结束,线程继续运行直到结束,称为分离线程

joinable()

  • 调用这个函数会返回一个布尔值,为true代表当前线程可以调用join()或者detach()函数,否则不能调用
  • 如果不进行这个判断强行调用join()或者detach()函数,程序或报错

线程调用类成员函数

  • 线程在调用类成员函数的时候,需要传递类函数的地址,以及类对象的指针(或者引用)作为第一个参数
#include<iostream>
#include<memory>
#include<thread>
class A{
public:
	void foo(){
		cout<<"Hello world"<<endl;
}
};

int main(){
	shared_ptr<A> a=make_shared<A>();
	thread thread1(&A::foo(),a);
	thread1.join();
}
  • 这里类对象指针采用指针指针避免释放空间时导致的空指针异常,智能指针会在这个指针不被需要时调用析构函数释放掉内存

数据未定义异常

  • 当函数需要传递的参数为引用类型时,我们传递一个临时变量会报错,因为临时变量在使用完就会被释放掉,这是x可能指向就为空
  • 我们可以通过加上ref来解决这个问题
void foo(int &x){
	int x=0;
}
int main(){
	thread thread1(foo,1);
	thread1.join();
}
  • 使用ref后正常,这里定义一个变量a,利用变量a与直接传1本质是一样的传递的都不是引用类型,所以a不用ref也会报错
  • 引用指向局部变量也可能会报错,局部变量只是在当前函数作用域内生效,当前a定义在了main函数里面所以不会报错,但是如果是在其他函数里面函数结束a就会被释放掉,但是线程还在继续就会出现空指针异常。
void foo(int &x){
	int x=0;
}
int main(){
	int a=1;
	thread thread1(foo,ref(a));
	thread1.join();
}
  • 如果函数foo参数不是引用类型的,而是int x ,那么直接串进去一个a是没有问题的,使用ref就表示我需要串引用类型的数据

线程调用的类函数为私有函数

  • 这个就通过友元来解决

更多推荐