多线程基础

由于单进程的处理能力差;而多CPU的、多进程的并行处理,由于进程间的切换也使得性能不佳。因此多线程并发性能够有效的解决这个问题,能够有效的克服这个问题。
本文参考视频:https://space.bilibili.com/182674044

一、thread类

在thread头文件中的thread类是对线程的描述。class thread 主要有以下的成员函数:

  • join()。调用该函数可以阻塞该进程。直至线程执行结束。
  • detach()。分离线程,将当前执行的线程实例和线程对象分离。线程实例执行完毕,释放掉申请的资源。
  • thread类处理能够接受普通函数Object,还能够接受Lambda等callable object。

1、普通函数

void func(int a,int b)
{
	cout<<"this is func thread"<<endl;
	cout<<(a + b)<<endl;
}
int main()
{
	thread th = thread(func(),1,2);
	th.join();
	cout<<"this is main thread"<<endl;
}
  • 这里就是main thread和func thread,两个线程并发执行。
//运行结果
this is func thread
3
this is main thread

2、Lambda

这里使用一个测试时间的用例说明,在创建线程的时候使用Lambda。

template<class T>
void measure(T&& func)
{
	using namespace std::chrono;
	auto start = system_clock::now();
	func();
	duration<double>diff = system_clock::now() - start;
	cout<<"运行了"<<diff.count()<<"second"<<endl;
}
void sum()
{
	int s = 0;
	for(int i = 0;i < 10000;++i
	{
		s += 1;
	}
}
// 使用
int main()
{
	measure([](){
	sum();
	})
}

二、使用多线程加速处理

long sum_future(int start,int end)
{
	long s = 0;
	for(int i = start;i < end;++i) s += i;
	return s;
}

const int num = 10000000;
int main()
{
	//	count个线程并发
	int count = 4;
	measure([](){
	vector<future<long>>vf;
	vf.reserve(count);
	for(int i = 0;i < K;++i)
	{
		//将num分为count部分,分给count个线程并发执行相加操作
		vf.push_back(async(sum_furture,i == 0?0:(num/ count) * i,(num / count) * (i + 1)));
	}
	long ans = 0;
	for(int i = 0;i < count;++i)
	{
		ans += vf[i].get();
	}
	cout<<ans<<endl;
	});
	
	// 使用单线程
	measure([](){
		long ans = sum_furture(0,num);
	});
	
}
  • 上述代码:将0-1000000分给四个线程进行并发相加操作,和一个线程执行0-10000000相加操作。运行时间上的差异。
//运行结果
49999995000000
运行了:0.009138second
49999995000000
运行了:0.025976second
  • 可以看出,多个线程的并发执行能够减少运行时间。但并不是严格的4倍关系。

三、多线程的问题

由于多个线程的并发访问,共享变量,因此会出现一定的问题。

void mutex_sum(int& s)
{
	for(int i = 0;i < 10000;++i) s++;
}

int main()
{
	measure([](){
	vector<thread>v;
	int s = 0;
	for(int i = 0;i < 4;++i)
	{
		v.emplace_back(mutex_sum,std::ref(s));
	}
	for(int i = 0;i < 4:++i)
	{
		v[i].join();
	}
	cout<<s<<endl;
	});
	return 0;
}
  • 这个时候s的值并不是4个线程进行0-10000的和,即40000.结果应该比40000小。这是因为线程间交错执行for的相加。例如thread1执行i = 100了,但是thread2执行到i = 20,那么thread下一轮的i将变为20了。这就导致了和变小了。
  • 解决:在for循环中加上锁。让每个线程之间进行累加时,不互相干扰。
#include<mutex>
std::mutex mux;
void mutex_sum(int& s)
{
	mux.lock();
	for(int i = 0;i < 10000;++i) s++;
	mux.unlock();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值