1.了解并发,线程,进程
并发:两个或多个独立活动的同时进行(而单核CPU通过上下文切换的方式实现并发其成为并发假象)
线程:运行代码的一个途径,且一个进程中只有一个主线程
(线程可以是一个运行代码的通道,路径,我们可以自己创建多个线程)
进程:
计算机关某一个程序关于某一个数据集合上的一次运行活动。
进程是线程的容器,一个进程可以包含多个线程。
而你也可以简单理解成它是exe的运行,应用程序的进行状态,也就是你打开某软件时的过程
(例如你打开一个软件,其图片显示和音乐播放,就是两个线程,而这两个及多个线程构成了进程)
2.并发实现的过程
(1)多进程实现并发(主要解决的是进程间通信的过程)【但我不会,所以不写】
a.一个电脑上,管道,文件,消息队列,内存共享
b.不同电脑通过SOCKET网络通信实现
(2)单个进程,多个线程实现并发,就是一个主线程多个子线程实现并发【主要写的是这个】
3.线程的多种创建方式
a.普通函数的创建方式
b.带参的方式创建线程
c.Lambda表达式创建线程
d.通过类对像创建线程
e.通过类的成员函数创建线程
(还有一个是根据智能指针创建,但我还是新手,不太熟练,所以没写,上述几个的实例下面有写)
4.基本知识
c++t头文件的创建#include<iostrean>
线程的头文件#include<thread>
以及using namespace std;
处理(每一个线程只能处理一次join/detach,不能同时使用,并且只能使用一次)
join():阻赛主线程,先子线程执行结束,再主线程(但也要看主线程的东西在代码位于join处理前后)
detach():主线程和子线程分别执行,也就叫把子线程驻留后台
(如果程序过多,可以使用joinable()来检查是否可以用detch/join,判断当前线程是否可以做join或者deatch过程,可以返回ture,不可以flase)如:
if (test1.joinable())//这个test1是自己创建的线程
{
test1.detach();
}
else
{
cout << "子线程已被处理" << endl;
}
5.实例
《1》普通函数的多线程创建
#include<iostream>
#include<thread>
using namespace std;
void hehe(int num)
{
num++;
cout << "zxc " <<num<< endl;
}
int main()
{
int num = 0;
thread test1(hehe,num);//创建线程
cout << "主线程" << endl;
cout << "hhh" << num << endl;
test1.join();//线程处理
return 0;
}
这里输出的值为
主线程
hhh0
zxc 1
《2》带参的方式创建线程
#include
#include<thread>
using namespace std;
void hehe(int&num)
{
num++;
cout << "zxc " << num << endl;
}
int main()
{
int num = 0;
thread test1(hehe,std::ref(num));//创建线程,传参数用std::ref()进行传参
test1.join();//线程处理
cout << "主线程" << endl;
cout << "hhh" << num << endl;
return 0;
}
其输出值为
zxc 1
主线程
hhh1
《3》Lambda表达式创建线程
Lambda表达式[]()->{}//即为捕获数据,函数参数,判断是否存在异常,指定一个一个返回值
如[](){cout<<"输出数据"<<endl};//这是利用Lambda语法写的一个输出函数的语法,而后接个()可以直接调用
#include
#include<thread>
using namespace std;
int main()
{
int(*imap)(int, int) = nullptr;
imap = [](int a, int b)->int {return a + b; };
thread test1([](){cout << "子线程" << endl; });
cout << imap(1, 2) << endl;
test1.join();
cout << "主线程" << endl;
[] {cout << "helloword" << endl; }();//打印函数的直接调用
return 0;
}
《4》通过类对像创建线程
#include
#include<thread>
using namespace std;
class MM
{
public:
void operator()()//这是操作符重载
{
cout << "子线程" << endl;
}
};
int main()
{
MM n;
thread test1(n);
test1.join();//使用对像充当线程处理函数
thread test2((MM()));//两个括号是防止其解析成函数
test2.join();//利用无名对象形式;无名对象加()表示调用里面的函数
cout << "主线程" << endl;
return 0;
}
《5》通过类的成员函数创建线程
#include
#include<thread>
using namespace std;
class MM
{
public:
void print(int& num)
{
num = 1001;
cout << "子线程" << this_thread::get_id() << endl;
}
};
int main()
{
int num = 1007;
MM mm;
thread test1(&MM::print, mm, ref(num));//需要告诉 是哪个对象
test1.join();
cout << "主线程" << this_thread::get_id() << endl;////this_thread是获取线程id
return 0;
}
//可能我所写的东西还有错误,水平还有待提高,但希望这篇文章可以帮助你更加了解线程的有关知识,也希望有人给我建议,谢谢!