c++多线程全局变量可见性问题

最近学习多线程编程的时候,测试加锁不加锁的时候,碰到了一个不能理解的现象,通过搜索,发现多线程编程的坑很深,需要考虑很多方面的情况,如编译器优化,内存模型,cpu架构。

现象:没有使用锁的情况下,两个线程访问同一个全局变量,一个线程修改了该全局变量后,在另一个线程中始终无法发现修改的值。

大致的代码描述:

int a = 0;
void * threadFun1(void *)
{
	a = 1;
}

void * threadFun2(void *)
{
	while (1)
	{
		if (a == 1)
		{
			//do something
		}
	}
}	

线程函数threadFun2始终没有完成do something的任务,原因是获取到a的值始终是0,并没有刷新为由线程函数threadFun1修改的值1。
本现象的原因是编译器优化造成的,线程函数threadFun2中由于频繁的访问aa的值用的是本线程缓存的值,因此不能看到主存中a的新值。测试下面两种方法有效:

  1. 设置编译器不优化。cmake中加入set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -00")
  2. 使用volatile关键字,强制每次从内存读取或刷新变量的值。volatile int a = 0

这种现象就是共享变量的可见性问题,上面的两种方法都不是解决问题的真正方法,真正的方法是加锁,保证每次只有一个线程能访问共享的变量,并且刷新和读取最新的内存值。

参考连接:
https://www.cnblogs.com/soaringEveryday/p/4418604.html
https://blog.csdn.net/u012887385/article/details/57984439
https://www.codenong.com/18599012/
https://www.it-swarm.dev/zh/c++/什么时候使用volatile多线程?/970260499/
https://changkun.de/modern-cpp/zh-cn/07-thread/index.html

你可能感兴趣的:(杂项笔记)