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

杂项笔记 专栏收录该内容
16 篇文章 1 订阅

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

  • 1
    点赞
  • 2
    评论
  • 6
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 2 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

biglamp

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值