C++多线程高并发,原子操作atomic

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_40666620/article/details/102653476

首先看一下没有原子操作,多个线程对同一个整形++

这里使用的是互斥量进行加锁,加了两千万此,花了大约4.5秒

void threadEntryFunc()
{
	//大约4.5秒
	for (int i = 1; i <= 10000000; i++)
	{
		myMutex.lock();
		myNum++;
		myMutex.unlock();
	}
}
int main()
{
	std::thread myThread1(threadEntryFunc);
	std::thread myThread2(threadEntryFunc);
	myThread1.join();
	myThread2.join();
	std::cout << "the final result is " << myNum2 << std::endl;
}

原子操作改进

什么是原子操作?和互斥量有什么不同?
原子操作和互斥量不同的是 互斥量指的是进行加锁和释放锁,之间的代码段以同步的方式进行 而原子操作指的是对某个变量进行操作,对这个变量进行的操作都是不可分割的, ++就必须加上1,整个汇编中间的操作都被视为一整个操作,不能分割,这就造成了原子性 并且原子操作在效率上要远远高于互斥量的加锁解锁

//原子操作的变量声明,至于这个变量的用法,没有什么太大变化
std::atomic<int> myNum2= 0;
void threadEntryFunc()
{
	//大约1.7秒左右,可以知道,效率大大提升
	for (int i = 0; i < 10000000; i++)
	{
		myNum2++;
	}
}
int main()
{
	std::thread myThread1(threadEntryFunc);
	std::thread myThread2(threadEntryFunc);
	myThread1.join();
	myThread2.join();
	std::cout << "the final result is " << myNum2 << std::endl;
}

原子操作时间,主线程中关闭子线程

//原子变量声明
std::atomic<bool> isRunning = true;
//线程入口函数
void threadEntryFunc2()
{
//循环判断是否主线程中关闭了
	while (isRunning)
	{
		std::cout << "线程 " << std::this_thread::get_id() << "运行中" << std::endl;
		//线程休眠1秒
		std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	}
	std::cout << "线程 " << std::this_thread::get_id() << "执行结束"<< std::endl;
}


int main()
{
	std::thread myThread1(threadEntryFunc2);
	std::thread myThread2(threadEntryFunc2);
	std::thread myThread3(threadEntryFunc2);
	//主线程等待10秒看运行结果
	std::this_thread::sleep_for(std::chrono::milliseconds(5000));
	isRunning = false;
	myThread1.join();
	myThread2.join();
	myThread3.join();
	std::cout << "the final result is " << myNum2 << std::endl;
}

运行结果如下,可以分析出,主线程只要把握住原子操作的bool值,即可决定子线程的运行状态
在这里插入图片描述

atomic注意点

虽然是原子操作,但是使用的操作方法是有要求的,如下:
想一想,从汇编的角度,++,--都是某个变量本身的操作,而x = x+1 这就需要使用寄存器,把x先存到一个寄存器中,寄存器中值+1,在给x的地址赋上新的值, 这种操作本身就不是原子操作所指的某个变量本身进行的操作

#include <atomic>
std::atomic<int> myNum = 0;
void method1()
{
	for(int i = 0 ; i < 10000000 ; i++)
	{
		//这种写法肯定是不行的,支持的写法有
		//++
		//--
		//+=
		//-=
		//!=
		//是这种结构的
		myNum = myNum+1;
	}
}
int main()
{
	std::thread myThread1(method1);
	std::thread myThread2(method1);
	myThread1.join();
	myThread2.join();
	std::cout<<"the answer is "<<myNum<<std::endl;
}

猜你喜欢

转载自blog.csdn.net/qq_40666620/article/details/102653476