C++中mutable与volatile的深入理解

2020-01-06 19:43:36刘景俊

在多线程环境下,volatile可用作内存同步手段。例如多线程爆破密码:


volatile bool found = false;

void run(string target) {
while (!found) {
// 计算字典口令的哈希
if (target == hash) {
found = true;
break;
}
}
}

在volatile的修饰下,每次循环都会检查内存中的值,达到同步的效果。

需要注意的是,volatile的值可能随时会变,期间会导致非预期的结果。例如下面的例子求平方和:


double square(volatile double a, volatile double b) {
return (a + b) * (a + b);
}

a和b都是随时可变的,所以上述代码中的第一个a + b可能和第二个不同,导致出现非预期的结果。这种情况下,正确做法是将值赋予常规变量,然后再相乘:


double square(volatile double a, volatile double b) {
double c = a + b;
return c * c;
}

一般说来,volatile用在如下的几个地方: 

1. 中断服务程序中修改的供其它程序检测的变量需要加volatile; 

2. 多任务环境下各任务间共享的标志应该加volatile; 

3. 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能有不同意义;

总结

mutable只能用与类变量,不能与const同时使用;在const修饰的方法中,mutable变量数值可以发生改变;
volatile只是运行期变量的值随时可能改变,这种改变即可能来自其他线程,也可能来自外部系统。