众所周知,mutex保证了读写的可控性,volatile则保证读写的实时性,这种实时性至少包括两个方面:
1.将中断、其他线程、其他设备等的行为纳入考虑
2.阻止编译器优化
在多线程共享数据时(我指的是简单地使用变量而非用到某些库的功能),
即使用了mutex,我们并没有保证阻止编译器的优化,
除非我们对自己的程序流程以及编译器极有把握,
不然不能排除极少数被优化掉的情况,举个例子:
void fun()
{
// 因为优化、内联等原因,不能保证函数对外的实时性
// "通俗"地讲,函数内的某些变量取值可能来自寄存器
a = b;
}
当然,我可以不开优化。——但是有时候我就是想要优化。
那能不能局部禁止优化?——听说没有。
那就老老实实加上volatile吧?——可以,但是比较烦,举些例子:
struct type { int a, b, c; };
// 又长又臭
volatile type a, b, *volatile c;
// 错误
a = b;
// 我靠。。。
a.a = b.a;
a.b = b.b;
a.c = b.c;
怎么办?用也不是,不用也不是。。。
于是冥思苦想,想到个法子:
void fun()
{
if(volatile char a = 0) return;
// "通俗"地讲,函数内的所有第一次取值都将来自内存
a = b;
}
VS2019亲测有效,并且我通俗地称之为:
#define clear_register if(volatile char a = 0) return;