C++多线程的6种创建方法

配合B站视频看添加链接描述

1. 并发、进程、线程概念:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2 创建线程:

普通函数方法创建线程

包含头文件,调用thread类创建一个线程对象;

#include <thread>
#include <iostream>
using namespace std;

void print(){
    
    
	cout<<"子线程"<<endl;
}
int main(){
    
    
	thread test1(print);
	cout<<"主线程"<<endl;
	return 0;
}

此时,执行代码会出错,会调用abort 函数终止程序。
在这里插入图片描述

需要使用join 函数,详解join 和detach函数,汇合线程,阻塞主线程。

#include <thread>
#include <iostream>
#include <windows.h>
using namespace std;

void print(){
    
    
	Sleep(5000);//5m
	cout<<"子线程"<<endl;
}
int main(){
    
    
	thread test1(print);
	test1.join();//阻塞
	cout<<"主线程"<<endl;
	return 0;
}

执行程序,5s后显示:
在这里插入图片描述

#include <thread>
#include <iostream>
#include <windows.h>
using namespace std;

void print1(){
    
    
	Sleep(5000);//5m
	cout<<"子线程"<<endl;
}
void print2(){
    
    
	Sleep(5000);//5m
	cout<<"子线程"<<endl;
}
int main(){
    
    
	thread test1(print1);
	thread test2(print2);
	test1.join();//阻塞
	test2.join();//阻塞
	cout<<"主线程"<<endl;
	return 0;
}

等5s,窗口显示:
在这里插入图片描述
因为这两个线程互不影响。

#include <thread>
#include <iostream>
#include <windows.h>
using namespace std;

void print(){
    
    
	Sleep(5000);//5m
	cout<<"子线程"<<endl;
}
int main(){
    
    
	thread test1(print);
	test1.detch();//
	cout<<"主线程"<<endl;
	return 0;
}

则窗口显示为:
在这里插入图片描述
因为子线程和主线程互不影响,主线程执行完了,子线程还没执行完。(子线程驻留后台)。
当线程detch 后就不能join 了。
joinable函数,判断当前线程是否可以做join 或者detch,可以返回真,不可以返回假。

#include <thread>
#include <iostream>
#include <windows.h>
using namespace std;

void print(){
    
    
	Sleep(5000);//5m
	cout<<"子线程"<<endl;
}
int main(){
    
    
	thread test1(print);
	test1.detch();//
	cout<<"主线程"<<endl;
	if(test1.joinable()){
    
    
		test1.detch();
	}
	else
		cout<<"子线程已被处理"<<endl;
	return 0;
}

窗口显示为:

通过类和对象创建线程

#include <thread>
#include <iostream>
#include <windows.h>
using namespace std;

class MM{
    
    
public:
	void operator()(){
    
    //重载()
		cout<<"子线程启动"<<endl;
	}
};

int main(){
    
    
	MM mm;//对象充当线程处理函数
	thread test1(mm);
	//上面也可以写成:
	//thread test1((MM()))//创建无名对象。MM()外要加括号,防止解析为函数。
	
	test1.join();//
	cout<<"ILOVEYOU"<<endl;
	
	return 0;
}

在这里插入图片描述

Lambda表达式创建

在这里插入图片描述
在这里插入图片描述

带参的方式创建

#include <iostream>
#include <thread>
using namespace std;
void printInfo(int & num){
    
    
	cout<<"线程号为"<<num<<endl;
}

int main(){
    
    
	int num=0;
	thread test1(printInfo,num);//此行有问题
	test1.join();
	cout<<"主线程"<<endl;
	return 0;
}

此时编译则报错,需要将有问题的那行改为

thread test1(printInfo,std::ref(num));
//std::ref用于包装引用传递值;

这样就没错了;
在这里插入图片描述

智能指针创建

在这里插入图片描述
move :移动语义。

类的成员函数创建

在这里插入图片描述
&MM::print可以获取Print 的函数地址。
在这里插入图片描述

多线程中数据混乱问题

假设有 4 个线程 A、B、C、D,当前一个线程 A 对内存中的共享资源进行访问的时候,其他线程 B, C, D 都不可以对这块内存进行操作,直到线程 A 对这块内存访问完毕为止,B,C,D 中的一个才能访问这块内存----线程同步的概念。

发现一个C++多线程 的宝藏博客:添加链接描述

Guess you like

Origin blog.csdn.net/Aristotle__/article/details/121890684